1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
25 * \file gl4GPUShaderFP64Tests.cpp
26 * \brief Implements conformance tests for "GPU Shader FP64" functionality.
27 */ /*-------------------------------------------------------------------*/
29 #include "gl4cGPUShaderFP64Tests.hpp"
30 #include "gluContextInfo.hpp"
31 #include "glwFunctions.hpp"
32 #include "tcuMatrix.hpp"
33 #include "tcuTestLog.hpp"
38 #include "deUniquePtr.hpp"
39 #include "tcuMatrixUtil.hpp"
40 #include "tcuVectorUtil.hpp"
50 const glw::GLenum Utils::programInfo::ARB_COMPUTE_SHADER = 0x91B9;
54 * @param context Test context
56 Utils::programInfo::programInfo(deqp::Context& context)
58 , m_compute_shader_id(0)
59 , m_fragment_shader_id(0)
60 , m_geometry_shader_id(0)
61 , m_program_object_id(0)
62 , m_tesselation_control_shader_id(0)
63 , m_tesselation_evaluation_shader_id(0)
64 , m_vertex_shader_id(0)
66 /* Nothing to be done here */
72 Utils::programInfo::~programInfo()
75 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
77 /* Make sure program object is no longer used by GL */
80 /* Clean program object */
81 if (0 != m_program_object_id)
83 gl.deleteProgram(m_program_object_id);
84 m_program_object_id = 0;
88 if (0 != m_compute_shader_id)
90 gl.deleteShader(m_compute_shader_id);
91 m_compute_shader_id = 0;
94 if (0 != m_fragment_shader_id)
96 gl.deleteShader(m_fragment_shader_id);
97 m_fragment_shader_id = 0;
100 if (0 != m_geometry_shader_id)
102 gl.deleteShader(m_geometry_shader_id);
103 m_geometry_shader_id = 0;
106 if (0 != m_tesselation_control_shader_id)
108 gl.deleteShader(m_tesselation_control_shader_id);
109 m_tesselation_control_shader_id = 0;
112 if (0 != m_tesselation_evaluation_shader_id)
114 gl.deleteShader(m_tesselation_evaluation_shader_id);
115 m_tesselation_evaluation_shader_id = 0;
118 if (0 != m_vertex_shader_id)
120 gl.deleteShader(m_vertex_shader_id);
121 m_vertex_shader_id = 0;
127 * @param compute_shader_code Compute shader source code
128 * @param fragment_shader_code Fragment shader source code
129 * @param geometry_shader_code Geometry shader source code
130 * @param tesselation_control_shader_code Tesselation control shader source code
131 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
132 * @param vertex_shader_code Vertex shader source code
133 * @param varying_names Array of strings containing names of varyings to be captured with transfrom feedback
134 * @param n_varying_names Number of varyings to be captured with transfrom feedback
136 void Utils::programInfo::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
137 const glw::GLchar* geometry_shader_code,
138 const glw::GLchar* tesselation_control_shader_code,
139 const glw::GLchar* tesselation_evaluation_shader_code,
140 const glw::GLchar* vertex_shader_code, const glw::GLchar* const* varying_names,
141 glw::GLuint n_varying_names)
143 /* GL entry points */
144 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
146 /* Create shader objects and compile */
147 if (0 != compute_shader_code)
149 m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER);
150 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
152 compile(m_compute_shader_id, compute_shader_code);
155 if (0 != fragment_shader_code)
157 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
158 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
160 compile(m_fragment_shader_id, fragment_shader_code);
163 if (0 != geometry_shader_code)
165 m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
166 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
168 compile(m_geometry_shader_id, geometry_shader_code);
171 if (0 != tesselation_control_shader_code)
173 m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
174 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
176 compile(m_tesselation_control_shader_id, tesselation_control_shader_code);
179 if (0 != tesselation_evaluation_shader_code)
181 m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
182 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
184 compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
187 if (0 != vertex_shader_code)
189 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
190 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
192 compile(m_vertex_shader_id, vertex_shader_code);
195 /* Create program object */
196 m_program_object_id = gl.createProgram();
197 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
199 /* Set up captyured varyings' names */
200 if (0 != n_varying_names)
202 gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
203 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
212 * @param shader_id Shader object id
213 * @param shader_code Shader source code
215 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
217 /* GL entry points */
218 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
220 /* Compilation status */
221 glw::GLint status = GL_FALSE;
223 /* Set source code */
224 gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
225 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
228 gl.compileShader(shader_id);
229 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
231 /* Get compilation status */
232 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
233 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
235 /* Log compilation error */
236 if (GL_TRUE != status)
238 glw::GLint length = 0;
239 std::vector<glw::GLchar> message;
241 /* Error log length */
242 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
243 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
245 /* Prepare storage */
246 message.resize(length);
249 gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
250 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
253 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
254 << &message[0] << "\nShader source\n"
255 << shader_code << tcu::TestLog::EndMessage;
257 TCU_FAIL("Failed to compile shader");
261 /** Attach shaders and link program
264 void Utils::programInfo::link() const
266 /* GL entry points */
267 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
270 glw::GLint status = GL_FALSE;
273 if (0 != m_compute_shader_id)
275 gl.attachShader(m_program_object_id, m_compute_shader_id);
276 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
279 if (0 != m_fragment_shader_id)
281 gl.attachShader(m_program_object_id, m_fragment_shader_id);
282 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
285 if (0 != m_geometry_shader_id)
287 gl.attachShader(m_program_object_id, m_geometry_shader_id);
288 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
291 if (0 != m_tesselation_control_shader_id)
293 gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
294 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
297 if (0 != m_tesselation_evaluation_shader_id)
299 gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
300 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
303 if (0 != m_vertex_shader_id)
305 gl.attachShader(m_program_object_id, m_vertex_shader_id);
306 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
310 gl.linkProgram(m_program_object_id);
311 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
313 /* Get link status */
314 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
315 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
318 if (GL_TRUE != status)
320 glw::GLint length = 0;
321 std::vector<glw::GLchar> message;
323 /* Get error log length */
324 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
325 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
327 message.resize(length);
330 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
331 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
334 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
335 << &message[0] << tcu::TestLog::EndMessage;
337 TCU_FAIL("Failed to link program");
341 /** Retrieves base type of user-provided variable type. (eg. VARIABLE_TYPE_DOUBLE for double-precision
344 * @param type Variable type to return base type for.
346 * @return Requested value or VARAIBLE_TYPE_UNKNOWN if @param type was not recognized.
348 Utils::_variable_type Utils::getBaseVariableType(_variable_type type)
350 _variable_type result = VARIABLE_TYPE_UNKNOWN;
354 case VARIABLE_TYPE_BOOL:
356 result = VARIABLE_TYPE_BOOL;
361 case VARIABLE_TYPE_DOUBLE:
362 case VARIABLE_TYPE_DMAT2:
363 case VARIABLE_TYPE_DMAT2X3:
364 case VARIABLE_TYPE_DMAT2X4:
365 case VARIABLE_TYPE_DMAT3:
366 case VARIABLE_TYPE_DMAT3X2:
367 case VARIABLE_TYPE_DMAT3X4:
368 case VARIABLE_TYPE_DMAT4:
369 case VARIABLE_TYPE_DMAT4X2:
370 case VARIABLE_TYPE_DMAT4X3:
371 case VARIABLE_TYPE_DVEC2:
372 case VARIABLE_TYPE_DVEC3:
373 case VARIABLE_TYPE_DVEC4:
375 result = VARIABLE_TYPE_DOUBLE;
380 case VARIABLE_TYPE_INT:
381 case VARIABLE_TYPE_IVEC2:
382 case VARIABLE_TYPE_IVEC3:
383 case VARIABLE_TYPE_IVEC4:
385 result = VARIABLE_TYPE_INT;
390 case VARIABLE_TYPE_UINT:
391 case VARIABLE_TYPE_UVEC2:
392 case VARIABLE_TYPE_UVEC3:
393 case VARIABLE_TYPE_UVEC4:
395 result = VARIABLE_TYPE_UINT;
400 case VARIABLE_TYPE_FLOAT:
401 case VARIABLE_TYPE_MAT2:
402 case VARIABLE_TYPE_MAT2X3:
403 case VARIABLE_TYPE_MAT2X4:
404 case VARIABLE_TYPE_MAT3:
405 case VARIABLE_TYPE_MAT3X2:
406 case VARIABLE_TYPE_MAT3X4:
407 case VARIABLE_TYPE_MAT4:
408 case VARIABLE_TYPE_MAT4X2:
409 case VARIABLE_TYPE_MAT4X3:
410 case VARIABLE_TYPE_VEC2:
411 case VARIABLE_TYPE_VEC3:
412 case VARIABLE_TYPE_VEC4:
414 result = VARIABLE_TYPE_FLOAT;
421 TCU_FAIL("Unrecognized variable type");
423 } /* switch (type) */
428 /** Returns size (in bytes) of a single component of a base variable type.
430 * @param type Base variable type to use for the query.
432 * @return Requested value or 0 if @param type was not recognized.
434 unsigned int Utils::getBaseVariableTypeComponentSize(_variable_type type)
436 unsigned int result = 0;
440 case VARIABLE_TYPE_BOOL:
441 result = sizeof(bool);
443 case VARIABLE_TYPE_DOUBLE:
444 result = sizeof(double);
446 case VARIABLE_TYPE_FLOAT:
447 result = sizeof(float);
449 case VARIABLE_TYPE_INT:
450 result = sizeof(int);
452 case VARIABLE_TYPE_UINT:
453 result = sizeof(unsigned int);
458 TCU_FAIL("Unrecognized variable type");
460 } /* switch (type) */
465 /** Returns component, corresponding to user-specified index
466 * (eg. index:0 corresponds to 'x', index:1 corresponds to 'y',
469 * @param index Component index.
471 * @return As per description.
473 unsigned char Utils::getComponentAtIndex(unsigned int index)
475 unsigned char result = '?';
494 TCU_FAIL("Unrecognized component index");
501 /** Get _variable_type representing double-precision type with given dimmensions
503 * @param n_columns Number of columns
504 * @param n_row Number of rows
506 * @return Corresponding _variable_type
508 Utils::_variable_type Utils::getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
510 Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
512 static const _variable_type types[4][4] = {
513 { VARIABLE_TYPE_DOUBLE, VARIABLE_TYPE_DVEC2, VARIABLE_TYPE_DVEC3, VARIABLE_TYPE_DVEC4 },
514 { VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT2, VARIABLE_TYPE_DMAT2X3, VARIABLE_TYPE_DMAT2X4 },
515 { VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT3X2, VARIABLE_TYPE_DMAT3, VARIABLE_TYPE_DMAT3X4 },
516 { VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT4X2, VARIABLE_TYPE_DMAT4X3, VARIABLE_TYPE_DMAT4 }
519 type = types[n_columns - 1][n_rows - 1];
524 /** Returns a single-precision equivalent of a double-precision floating-point variable
527 * @param type Double-precision variable type. Only VARIABLE_TYPE_D* variable types
530 * @return Requested GLSL type.
532 std::string Utils::getFPVariableTypeStringForVariableType(_variable_type type)
534 std::string result = "[?]";
538 case VARIABLE_TYPE_DOUBLE:
541 case VARIABLE_TYPE_DMAT2:
544 case VARIABLE_TYPE_DMAT2X3:
547 case VARIABLE_TYPE_DMAT2X4:
550 case VARIABLE_TYPE_DMAT3:
553 case VARIABLE_TYPE_DMAT3X2:
556 case VARIABLE_TYPE_DMAT3X4:
559 case VARIABLE_TYPE_DMAT4:
562 case VARIABLE_TYPE_DMAT4X2:
565 case VARIABLE_TYPE_DMAT4X3:
568 case VARIABLE_TYPE_DVEC2:
571 case VARIABLE_TYPE_DVEC3:
574 case VARIABLE_TYPE_DVEC4:
580 TCU_FAIL("Unrecognized variable type");
582 }; /* switch (type) */
587 /** Returns GL data type enum corresponding to user-provided base variable type.
589 * @param type Base variable type to return corresponding GLenum value for.
591 * @return Corresponding GLenum value or GL_NONE if the input value was not
594 glw::GLenum Utils::getGLDataTypeOfBaseVariableType(_variable_type type)
596 glw::GLenum result = GL_NONE;
600 case VARIABLE_TYPE_BOOL:
603 case VARIABLE_TYPE_DOUBLE:
606 case VARIABLE_TYPE_FLOAT:
609 case VARIABLE_TYPE_INT:
612 case VARIABLE_TYPE_UINT:
613 result = GL_UNSIGNED_INT;
618 TCU_FAIL("Unrecognized variable type");
625 /** Return GLenum representing given <type>
627 * @param type Type of variable
629 * @return GL enumeration
631 glw::GLenum Utils::getGLDataTypeOfVariableType(_variable_type type)
633 glw::GLenum result = GL_NONE;
637 case VARIABLE_TYPE_BOOL:
640 case VARIABLE_TYPE_DOUBLE:
643 case VARIABLE_TYPE_DMAT2:
644 result = GL_DOUBLE_MAT2;
646 case VARIABLE_TYPE_DMAT2X3:
647 result = GL_DOUBLE_MAT2x3;
649 case VARIABLE_TYPE_DMAT2X4:
650 result = GL_DOUBLE_MAT2x4;
652 case VARIABLE_TYPE_DMAT3:
653 result = GL_DOUBLE_MAT3;
655 case VARIABLE_TYPE_DMAT3X2:
656 result = GL_DOUBLE_MAT3x2;
658 case VARIABLE_TYPE_DMAT3X4:
659 result = GL_DOUBLE_MAT3x4;
661 case VARIABLE_TYPE_DMAT4:
662 result = GL_DOUBLE_MAT4;
664 case VARIABLE_TYPE_DMAT4X2:
665 result = GL_DOUBLE_MAT4x2;
667 case VARIABLE_TYPE_DMAT4X3:
668 result = GL_DOUBLE_MAT4x3;
670 case VARIABLE_TYPE_DVEC2:
671 result = GL_DOUBLE_VEC2;
673 case VARIABLE_TYPE_DVEC3:
674 result = GL_DOUBLE_VEC3;
676 case VARIABLE_TYPE_DVEC4:
677 result = GL_DOUBLE_VEC4;
679 case VARIABLE_TYPE_FLOAT:
682 case VARIABLE_TYPE_INT:
685 case VARIABLE_TYPE_IVEC2:
686 result = GL_INT_VEC2;
688 case VARIABLE_TYPE_IVEC3:
689 result = GL_INT_VEC3;
691 case VARIABLE_TYPE_IVEC4:
692 result = GL_INT_VEC4;
694 case VARIABLE_TYPE_MAT2:
695 result = GL_FLOAT_MAT2;
697 case VARIABLE_TYPE_MAT2X3:
698 result = GL_FLOAT_MAT2x3;
700 case VARIABLE_TYPE_MAT2X4:
701 result = GL_FLOAT_MAT2x4;
703 case VARIABLE_TYPE_MAT3:
704 result = GL_FLOAT_MAT3;
706 case VARIABLE_TYPE_MAT3X2:
707 result = GL_FLOAT_MAT3x2;
709 case VARIABLE_TYPE_MAT3X4:
710 result = GL_FLOAT_MAT3x4;
712 case VARIABLE_TYPE_MAT4:
713 result = GL_FLOAT_MAT4;
715 case VARIABLE_TYPE_MAT4X2:
716 result = GL_FLOAT_MAT4x2;
718 case VARIABLE_TYPE_MAT4X3:
719 result = GL_FLOAT_MAT4x3;
721 case VARIABLE_TYPE_UINT:
722 result = GL_UNSIGNED_INT;
724 case VARIABLE_TYPE_UVEC2:
725 result = GL_UNSIGNED_INT_VEC2;
727 case VARIABLE_TYPE_UVEC3:
728 result = GL_UNSIGNED_INT_VEC3;
730 case VARIABLE_TYPE_UVEC4:
731 result = GL_UNSIGNED_INT_VEC4;
733 case VARIABLE_TYPE_VEC2:
734 result = GL_FLOAT_VEC2;
736 case VARIABLE_TYPE_VEC3:
737 result = GL_FLOAT_VEC3;
739 case VARIABLE_TYPE_VEC4:
740 result = GL_FLOAT_VEC4;
745 TCU_FAIL("Unrecognized variable type");
752 /** Get _variable_type representing integer type with given dimmensions
754 * @param n_columns Number of columns
755 * @param n_row Number of rows
757 * @return Corresponding _variable_type
759 Utils::_variable_type Utils::getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
761 Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
763 static const _variable_type types[4] = { VARIABLE_TYPE_INT, VARIABLE_TYPE_IVEC2, VARIABLE_TYPE_IVEC3,
764 VARIABLE_TYPE_IVEC4 };
768 TCU_FAIL("Not implemented");
772 type = types[n_rows - 1];
778 /** Returns te number of components that variables defined with user-specified type
779 * support. For matrix types, total amount of values accessible for the type will be
782 * @param type Variable type to return the described vale for.
784 * @return As per description or 0 if @param type was not recognized.
786 unsigned int Utils::getNumberOfComponentsForVariableType(_variable_type type)
788 unsigned int result = 0;
792 case VARIABLE_TYPE_BOOL:
793 case VARIABLE_TYPE_DOUBLE:
794 case VARIABLE_TYPE_FLOAT:
795 case VARIABLE_TYPE_INT:
796 case VARIABLE_TYPE_UINT:
803 case VARIABLE_TYPE_DVEC2:
804 case VARIABLE_TYPE_IVEC2:
805 case VARIABLE_TYPE_UVEC2:
806 case VARIABLE_TYPE_VEC2:
813 case VARIABLE_TYPE_DVEC3:
814 case VARIABLE_TYPE_IVEC3:
815 case VARIABLE_TYPE_UVEC3:
816 case VARIABLE_TYPE_VEC3:
823 case VARIABLE_TYPE_DVEC4:
824 case VARIABLE_TYPE_IVEC4:
825 case VARIABLE_TYPE_UVEC4:
826 case VARIABLE_TYPE_VEC4:
833 case VARIABLE_TYPE_DMAT2:
834 case VARIABLE_TYPE_MAT2:
841 case VARIABLE_TYPE_DMAT2X3:
842 case VARIABLE_TYPE_DMAT3X2:
843 case VARIABLE_TYPE_MAT2X3:
844 case VARIABLE_TYPE_MAT3X2:
851 case VARIABLE_TYPE_DMAT2X4:
852 case VARIABLE_TYPE_DMAT4X2:
853 case VARIABLE_TYPE_MAT2X4:
854 case VARIABLE_TYPE_MAT4X2:
861 case VARIABLE_TYPE_DMAT3:
862 case VARIABLE_TYPE_MAT3:
869 case VARIABLE_TYPE_DMAT3X4:
870 case VARIABLE_TYPE_DMAT4X3:
871 case VARIABLE_TYPE_MAT3X4:
872 case VARIABLE_TYPE_MAT4X3:
879 case VARIABLE_TYPE_DMAT4:
880 case VARIABLE_TYPE_MAT4:
889 TCU_FAIL("Unrecognized type");
891 } /* switch (type) */
896 /** Returns number of columns user-specified matrix variable type describes.
898 * @param type Variable type to use for the query. Only VARIABLE_TYPE_DMAT*
901 * @return As per description.
903 unsigned int Utils::getNumberOfColumnsForVariableType(_variable_type type)
905 unsigned int result = 0;
909 case VARIABLE_TYPE_BOOL:
910 case VARIABLE_TYPE_DOUBLE:
911 case VARIABLE_TYPE_FLOAT:
912 case VARIABLE_TYPE_INT:
913 case VARIABLE_TYPE_UINT:
914 case VARIABLE_TYPE_DVEC2:
915 case VARIABLE_TYPE_IVEC2:
916 case VARIABLE_TYPE_UVEC2:
917 case VARIABLE_TYPE_VEC2:
918 case VARIABLE_TYPE_DVEC3:
919 case VARIABLE_TYPE_IVEC3:
920 case VARIABLE_TYPE_UVEC3:
921 case VARIABLE_TYPE_VEC3:
922 case VARIABLE_TYPE_DVEC4:
923 case VARIABLE_TYPE_IVEC4:
924 case VARIABLE_TYPE_UVEC4:
925 case VARIABLE_TYPE_VEC4:
932 case VARIABLE_TYPE_DMAT2:
933 case VARIABLE_TYPE_DMAT2X3:
934 case VARIABLE_TYPE_DMAT2X4:
935 case VARIABLE_TYPE_MAT2:
936 case VARIABLE_TYPE_MAT2X3:
937 case VARIABLE_TYPE_MAT2X4:
944 case VARIABLE_TYPE_DMAT3:
945 case VARIABLE_TYPE_DMAT3X2:
946 case VARIABLE_TYPE_DMAT3X4:
947 case VARIABLE_TYPE_MAT3:
948 case VARIABLE_TYPE_MAT3X2:
949 case VARIABLE_TYPE_MAT3X4:
956 case VARIABLE_TYPE_DMAT4:
957 case VARIABLE_TYPE_DMAT4X2:
958 case VARIABLE_TYPE_DMAT4X3:
959 case VARIABLE_TYPE_MAT4:
960 case VARIABLE_TYPE_MAT4X2:
961 case VARIABLE_TYPE_MAT4X3:
970 TCU_FAIL("Unrecognized type");
972 } /* switch (type) */
977 /** Returns maximum number of uniform locations taken by user-specified double-precision
980 * @param type Variable type to use for the query. Only VARIABLE_TYPE_D* values are valid.
982 * @return As per description.
984 unsigned int Utils::getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type)
986 unsigned int result = 0;
990 case VARIABLE_TYPE_DOUBLE:
993 case VARIABLE_TYPE_DVEC2:
996 case VARIABLE_TYPE_DVEC3:
999 case VARIABLE_TYPE_DVEC4:
1002 case VARIABLE_TYPE_DMAT2:
1005 case VARIABLE_TYPE_DMAT2X3:
1008 case VARIABLE_TYPE_DMAT2X4:
1011 case VARIABLE_TYPE_DMAT3:
1014 case VARIABLE_TYPE_DMAT3X2:
1017 case VARIABLE_TYPE_DMAT3X4:
1020 case VARIABLE_TYPE_DMAT4:
1023 case VARIABLE_TYPE_DMAT4X2:
1026 case VARIABLE_TYPE_DMAT4X3:
1032 TCU_FAIL("Unrecognized type");
1034 } /* switch (type) */
1039 /** Get number of rows for given variable type
1041 * @param type Type of variable
1043 * @return Number of rows
1045 unsigned int Utils::getNumberOfRowsForVariableType(_variable_type type)
1047 unsigned int result = 0;
1051 case VARIABLE_TYPE_BOOL:
1052 case VARIABLE_TYPE_DOUBLE:
1053 case VARIABLE_TYPE_FLOAT:
1054 case VARIABLE_TYPE_INT:
1055 case VARIABLE_TYPE_UINT:
1062 case VARIABLE_TYPE_DVEC2:
1063 case VARIABLE_TYPE_IVEC2:
1064 case VARIABLE_TYPE_UVEC2:
1065 case VARIABLE_TYPE_VEC2:
1066 case VARIABLE_TYPE_DMAT2:
1067 case VARIABLE_TYPE_DMAT3X2:
1068 case VARIABLE_TYPE_DMAT4X2:
1069 case VARIABLE_TYPE_MAT2:
1070 case VARIABLE_TYPE_MAT3X2:
1071 case VARIABLE_TYPE_MAT4X2:
1078 case VARIABLE_TYPE_DVEC3:
1079 case VARIABLE_TYPE_IVEC3:
1080 case VARIABLE_TYPE_UVEC3:
1081 case VARIABLE_TYPE_VEC3:
1082 case VARIABLE_TYPE_DMAT2X3:
1083 case VARIABLE_TYPE_DMAT3:
1084 case VARIABLE_TYPE_DMAT4X3:
1085 case VARIABLE_TYPE_MAT2X3:
1086 case VARIABLE_TYPE_MAT3:
1087 case VARIABLE_TYPE_MAT4X3:
1094 case VARIABLE_TYPE_DVEC4:
1095 case VARIABLE_TYPE_IVEC4:
1096 case VARIABLE_TYPE_UVEC4:
1097 case VARIABLE_TYPE_VEC4:
1098 case VARIABLE_TYPE_DMAT2X4:
1099 case VARIABLE_TYPE_DMAT3X4:
1100 case VARIABLE_TYPE_DMAT4:
1101 case VARIABLE_TYPE_MAT2X4:
1102 case VARIABLE_TYPE_MAT3X4:
1103 case VARIABLE_TYPE_MAT4:
1112 TCU_FAIL("Unrecognized type");
1114 } /* switch (type) */
1119 /** Returns variable type of a matrix constructed by multiplying two matrices.
1121 * @param type_matrix_a L-side matrix type.
1122 * @param type_matrix_b R-side matrix type.
1124 * @return As per description.
1126 Utils::_variable_type Utils::getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a,
1127 _variable_type type_matrix_b)
1129 const unsigned int n_a_columns = Utils::getNumberOfColumnsForVariableType(type_matrix_a);
1130 const unsigned int n_a_components = Utils::getNumberOfComponentsForVariableType(type_matrix_a);
1131 const unsigned int n_a_rows = n_a_components / n_a_columns;
1132 const unsigned int n_b_columns = Utils::getNumberOfColumnsForVariableType(type_matrix_b);
1133 const unsigned int n_result_columns = n_b_columns;
1134 const unsigned int n_result_rows = n_a_rows;
1135 Utils::_variable_type result;
1137 switch (n_result_columns)
1141 switch (n_result_rows)
1144 result = VARIABLE_TYPE_DMAT2;
1147 result = VARIABLE_TYPE_DMAT2X3;
1150 result = VARIABLE_TYPE_DMAT2X4;
1155 TCU_FAIL("Unrecognized amount of rows in result variable");
1157 } /* switch (n_result_rows) */
1164 switch (n_result_rows)
1167 result = VARIABLE_TYPE_DMAT3X2;
1170 result = VARIABLE_TYPE_DMAT3;
1173 result = VARIABLE_TYPE_DMAT3X4;
1178 TCU_FAIL("Unrecognized amount of rows in result variable");
1180 } /* switch (n_result_rows) */
1187 switch (n_result_rows)
1190 result = VARIABLE_TYPE_DMAT4X2;
1193 result = VARIABLE_TYPE_DMAT4X3;
1196 result = VARIABLE_TYPE_DMAT4;
1201 TCU_FAIL("Unrecognized amount of rows in result variable");
1203 } /* switch (n_result_rows) */
1210 TCU_FAIL("Unrecognized amount of columns in result variable");
1212 } /* switch (n_result_columns) */
1218 /** Returns a string holding the value represented by user-provided variable, for which
1219 * the data are represented in @param type variable type.
1221 * @return As per description.
1223 std::string Utils::getStringForVariableTypeValue(_variable_type type, const unsigned char* data_ptr)
1225 std::stringstream result_sstream;
1229 case VARIABLE_TYPE_BOOL:
1230 result_sstream << *((bool*)data_ptr);
1232 case VARIABLE_TYPE_DOUBLE:
1233 result_sstream << *((double*)data_ptr);
1235 case VARIABLE_TYPE_FLOAT:
1236 result_sstream << *((float*)data_ptr);
1238 case VARIABLE_TYPE_INT:
1239 result_sstream << *((int*)data_ptr);
1241 case VARIABLE_TYPE_UINT:
1242 result_sstream << *((unsigned int*)data_ptr);
1247 TCU_FAIL("Unrecognized variable type requested");
1249 } /* switch (type) */
1251 return result_sstream.str();
1254 /** Returns variable type of a transposed matrix of user-specified variable type.
1256 * @param type Variable type of the matrix to be transposed.
1258 * @return Transposed matrix variable type.
1260 Utils::_variable_type Utils::getTransposedMatrixVariableType(Utils::_variable_type type)
1262 Utils::_variable_type result;
1266 case VARIABLE_TYPE_DMAT2:
1267 result = VARIABLE_TYPE_DMAT2;
1269 case VARIABLE_TYPE_DMAT2X3:
1270 result = VARIABLE_TYPE_DMAT3X2;
1272 case VARIABLE_TYPE_DMAT2X4:
1273 result = VARIABLE_TYPE_DMAT4X2;
1275 case VARIABLE_TYPE_DMAT3:
1276 result = VARIABLE_TYPE_DMAT3;
1278 case VARIABLE_TYPE_DMAT3X2:
1279 result = VARIABLE_TYPE_DMAT2X3;
1281 case VARIABLE_TYPE_DMAT3X4:
1282 result = VARIABLE_TYPE_DMAT4X3;
1284 case VARIABLE_TYPE_DMAT4:
1285 result = VARIABLE_TYPE_DMAT4;
1287 case VARIABLE_TYPE_DMAT4X2:
1288 result = VARIABLE_TYPE_DMAT2X4;
1290 case VARIABLE_TYPE_DMAT4X3:
1291 result = VARIABLE_TYPE_DMAT3X4;
1296 TCU_FAIL("Unrecognized double-precision matrix variable type.");
1298 } /* switch (type) */
1303 /** Get _variable_type representing unsigned integer type with given dimmensions
1305 * @param n_columns Number of columns
1306 * @param n_row Number of rows
1308 * @return Corresponding _variable_type
1310 Utils::_variable_type Utils::getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
1312 Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
1314 static const _variable_type types[4] = { VARIABLE_TYPE_UINT, VARIABLE_TYPE_UVEC2, VARIABLE_TYPE_UVEC3,
1315 VARIABLE_TYPE_UVEC4 };
1319 TCU_FAIL("Not implemented");
1323 type = types[n_rows - 1];
1329 /** Returns a literal corresponding to a GLSL keyword describing user-specified
1332 * @param type Variable type to use for the query.
1334 * @return Requested GLSL keyword or [?] if @param type was not recognized.
1336 std::string Utils::getVariableTypeString(_variable_type type)
1338 std::string result = "[?]";
1342 case VARIABLE_TYPE_BOOL:
1345 case VARIABLE_TYPE_BVEC2:
1348 case VARIABLE_TYPE_BVEC3:
1351 case VARIABLE_TYPE_BVEC4:
1354 case VARIABLE_TYPE_DOUBLE:
1357 case VARIABLE_TYPE_DMAT2:
1360 case VARIABLE_TYPE_DMAT2X3:
1363 case VARIABLE_TYPE_DMAT2X4:
1366 case VARIABLE_TYPE_DMAT3:
1369 case VARIABLE_TYPE_DMAT3X2:
1372 case VARIABLE_TYPE_DMAT3X4:
1375 case VARIABLE_TYPE_DMAT4:
1378 case VARIABLE_TYPE_DMAT4X2:
1381 case VARIABLE_TYPE_DMAT4X3:
1384 case VARIABLE_TYPE_DVEC2:
1387 case VARIABLE_TYPE_DVEC3:
1390 case VARIABLE_TYPE_DVEC4:
1393 case VARIABLE_TYPE_FLOAT:
1396 case VARIABLE_TYPE_INT:
1399 case VARIABLE_TYPE_IVEC2:
1402 case VARIABLE_TYPE_IVEC3:
1405 case VARIABLE_TYPE_IVEC4:
1408 case VARIABLE_TYPE_MAT2:
1411 case VARIABLE_TYPE_MAT2X3:
1414 case VARIABLE_TYPE_MAT2X4:
1417 case VARIABLE_TYPE_MAT3:
1420 case VARIABLE_TYPE_MAT3X2:
1423 case VARIABLE_TYPE_MAT3X4:
1426 case VARIABLE_TYPE_MAT4:
1429 case VARIABLE_TYPE_MAT4X2:
1432 case VARIABLE_TYPE_MAT4X3:
1435 case VARIABLE_TYPE_UINT:
1438 case VARIABLE_TYPE_UVEC2:
1441 case VARIABLE_TYPE_UVEC3:
1444 case VARIABLE_TYPE_UVEC4:
1447 case VARIABLE_TYPE_VEC2:
1450 case VARIABLE_TYPE_VEC3:
1453 case VARIABLE_TYPE_VEC4:
1459 TCU_FAIL("Unrecognized variable type");
1461 }; /* switch (type) */
1466 /** Check if GL context meets version requirements
1468 * @param gl Functions
1469 * @param required_major Minimum required MAJOR_VERSION
1470 * @param required_minor Minimum required MINOR_VERSION
1472 * @return true if GL context version is at least as requested, false otherwise
1474 bool Utils::isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor)
1476 glw::GLint major = 0;
1477 glw::GLint minor = 0;
1479 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1480 gl.getIntegerv(GL_MINOR_VERSION, &minor);
1482 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1484 if (major > required_major)
1486 /* Major is higher than required one */
1489 else if (major == required_major)
1491 if (minor >= required_minor)
1493 /* Major is equal to required one */
1494 /* Minor is higher than or equal to required one */
1499 /* Major is equal to required one */
1500 /* Minor is lower than required one */
1506 /* Major is lower than required one */
1511 /** Tells whether user-specified variable type corresponds to a matrix type.
1513 * @param type Variable type to use for the query.
1515 * @return true if the variable type describes a matrix, false otherwise.
1517 bool Utils::isMatrixVariableType(_variable_type type)
1519 return (type == VARIABLE_TYPE_MAT2 || type == VARIABLE_TYPE_MAT3 || type == VARIABLE_TYPE_MAT4 ||
1520 type == VARIABLE_TYPE_MAT2X3 || type == VARIABLE_TYPE_MAT2X4 || type == VARIABLE_TYPE_MAT3X2 ||
1521 type == VARIABLE_TYPE_MAT3X4 || type == VARIABLE_TYPE_MAT4X2 || type == VARIABLE_TYPE_MAT4X3 ||
1522 type == VARIABLE_TYPE_DMAT2 || type == VARIABLE_TYPE_DMAT3 || type == VARIABLE_TYPE_DMAT4 ||
1523 type == VARIABLE_TYPE_DMAT2X3 || type == VARIABLE_TYPE_DMAT2X4 || type == VARIABLE_TYPE_DMAT3X2 ||
1524 type == VARIABLE_TYPE_DMAT3X4 || type == VARIABLE_TYPE_DMAT4X2 || type == VARIABLE_TYPE_DMAT4X3);
1527 /** Tells whether user-specified variable type is scalar.
1529 * @return true if @param type is a scalar variable type, false otherwise.
1531 bool Utils::isScalarVariableType(_variable_type type)
1533 bool result = false;
1537 case VARIABLE_TYPE_BOOL:
1540 case VARIABLE_TYPE_DOUBLE:
1543 case VARIABLE_TYPE_FLOAT:
1546 case VARIABLE_TYPE_INT:
1549 case VARIABLE_TYPE_UINT:
1554 }; /* switch (type) */
1559 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
1561 * @param token Token string
1562 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
1563 * @param text String that will be used as replacement for <token>
1564 * @param string String to work on
1566 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
1567 std::string& string)
1569 const size_t text_length = strlen(text);
1570 const size_t token_length = strlen(token);
1571 const size_t token_position = string.find(token, search_position);
1573 string.replace(token_position, token_length, text, text_length);
1575 search_position = token_position + text_length;
1580 * @param context Rendering context.
1583 GPUShaderFP64Test1::GPUShaderFP64Test1(deqp::Context& context)
1584 : TestCase(context, "errors", "Verifies that various erroneous conditions related to double-precision "
1585 "float uniform support & glUniform*() / glUniformMatrix*() API "
1586 " are reported correctly.")
1587 , m_has_test_passed(true)
1588 , m_po_bool_arr_uniform_location(0)
1589 , m_po_bool_uniform_location(0)
1590 , m_po_bvec2_arr_uniform_location(0)
1591 , m_po_bvec2_uniform_location(0)
1592 , m_po_bvec3_arr_uniform_location(0)
1593 , m_po_bvec3_uniform_location(0)
1594 , m_po_bvec4_arr_uniform_location(0)
1595 , m_po_bvec4_uniform_location(0)
1596 , m_po_dmat2_arr_uniform_location(0)
1597 , m_po_dmat2_uniform_location(0)
1598 , m_po_dmat2x3_arr_uniform_location(0)
1599 , m_po_dmat2x3_uniform_location(0)
1600 , m_po_dmat2x4_arr_uniform_location(0)
1601 , m_po_dmat2x4_uniform_location(0)
1602 , m_po_dmat3_arr_uniform_location(0)
1603 , m_po_dmat3_uniform_location(0)
1604 , m_po_dmat3x2_arr_uniform_location(0)
1605 , m_po_dmat3x2_uniform_location(0)
1606 , m_po_dmat3x4_arr_uniform_location(0)
1607 , m_po_dmat3x4_uniform_location(0)
1608 , m_po_dmat4_arr_uniform_location(0)
1609 , m_po_dmat4_uniform_location(0)
1610 , m_po_dmat4x2_arr_uniform_location(0)
1611 , m_po_dmat4x2_uniform_location(0)
1612 , m_po_dmat4x3_arr_uniform_location(0)
1613 , m_po_dmat4x3_uniform_location(0)
1614 , m_po_double_arr_uniform_location(0)
1615 , m_po_double_uniform_location(0)
1616 , m_po_dvec2_arr_uniform_location(0)
1617 , m_po_dvec2_uniform_location(0)
1618 , m_po_dvec3_arr_uniform_location(0)
1619 , m_po_dvec3_uniform_location(0)
1620 , m_po_dvec4_arr_uniform_location(0)
1621 , m_po_dvec4_uniform_location(0)
1622 , m_po_float_arr_uniform_location(0)
1623 , m_po_float_uniform_location(0)
1624 , m_po_int_arr_uniform_location(0)
1625 , m_po_int_uniform_location(0)
1626 , m_po_ivec2_arr_uniform_location(0)
1627 , m_po_ivec2_uniform_location(0)
1628 , m_po_ivec3_arr_uniform_location(0)
1629 , m_po_ivec3_uniform_location(0)
1630 , m_po_ivec4_arr_uniform_location(0)
1631 , m_po_ivec4_uniform_location(0)
1632 , m_po_sampler_uniform_location(0)
1633 , m_po_uint_arr_uniform_location(0)
1634 , m_po_uint_uniform_location(0)
1635 , m_po_uvec2_arr_uniform_location(0)
1636 , m_po_uvec2_uniform_location(0)
1637 , m_po_uvec3_arr_uniform_location(0)
1638 , m_po_uvec3_uniform_location(0)
1639 , m_po_uvec4_arr_uniform_location(0)
1640 , m_po_uvec4_uniform_location(0)
1641 , m_po_vec2_arr_uniform_location(0)
1642 , m_po_vec2_uniform_location(0)
1643 , m_po_vec3_arr_uniform_location(0)
1644 , m_po_vec3_uniform_location(0)
1645 , m_po_vec4_arr_uniform_location(0)
1646 , m_po_vec4_uniform_location(0)
1650 /* Left blank intentionally */
1653 /** Deinitializes all GL objects that may have been created during
1656 void GPUShaderFP64Test1::deinit()
1658 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1662 gl.deleteProgram(m_po_id);
1669 gl.deleteShader(m_vs_id);
1675 /** Returns a string describing GL API function represented by user-provided enum.
1677 * @param func Uniform function to return the string for.
1679 * @return As per description. [?] will be returned if the function was not recognized.
1681 const char* GPUShaderFP64Test1::getUniformFunctionString(_uniform_function func)
1683 const char* result = "[?]";
1687 case UNIFORM_FUNCTION_1D:
1688 result = "glUniform1d";
1690 case UNIFORM_FUNCTION_1DV:
1691 result = "glUniform1dv";
1693 case UNIFORM_FUNCTION_2D:
1694 result = "glUniform2d";
1696 case UNIFORM_FUNCTION_2DV:
1697 result = "glUniform2dv";
1699 case UNIFORM_FUNCTION_3D:
1700 result = "glUniform3d";
1702 case UNIFORM_FUNCTION_3DV:
1703 result = "glUniform3dv";
1705 case UNIFORM_FUNCTION_4D:
1706 result = "glUniform4d";
1708 case UNIFORM_FUNCTION_4DV:
1709 result = "glUniform4dv";
1711 case UNIFORM_FUNCTION_MATRIX2DV:
1712 result = "glUniformMatrix2dv";
1714 case UNIFORM_FUNCTION_MATRIX2X3DV:
1715 result = "glUniformMatrix2x3dv";
1717 case UNIFORM_FUNCTION_MATRIX2X4DV:
1718 result = "glUniformMatrix2x4dv";
1720 case UNIFORM_FUNCTION_MATRIX3DV:
1721 result = "glUniformMatrix3dv";
1723 case UNIFORM_FUNCTION_MATRIX3X2DV:
1724 result = "glUniformMatrix3x2dv";
1726 case UNIFORM_FUNCTION_MATRIX3X4DV:
1727 result = "glUniformMatrix3x4dv";
1729 case UNIFORM_FUNCTION_MATRIX4DV:
1730 result = "glUniformMatrix4dv";
1732 case UNIFORM_FUNCTION_MATRIX4X2DV:
1733 result = "glUniformMatrix4x2dv";
1735 case UNIFORM_FUNCTION_MATRIX4X3DV:
1736 result = "glUniformMatrix4x3dv";
1745 /** Returns name of an uniform bound to user-provided location.
1747 * @param location Location of the uniform to return the name for.
1749 * @return As per description. [?] will be returned if the location was not
1752 const char* GPUShaderFP64Test1::getUniformNameForLocation(glw::GLint location)
1754 const char* result = "[?]";
1756 if (location == m_po_bool_arr_uniform_location)
1757 result = "uniform_bool_arr";
1758 else if (location == m_po_bool_uniform_location)
1759 result = "uniform_bool";
1760 else if (location == m_po_bvec2_arr_uniform_location)
1761 result = "uniform_bvec2_arr";
1762 else if (location == m_po_bvec2_uniform_location)
1763 result = "uniform_bvec2";
1764 else if (location == m_po_bvec3_arr_uniform_location)
1765 result = "uniform_bvec3_arr";
1766 else if (location == m_po_bvec3_uniform_location)
1767 result = "uniform_bvec3";
1768 else if (location == m_po_bvec4_arr_uniform_location)
1769 result = "uniform_bvec4_arr";
1770 else if (location == m_po_bvec4_uniform_location)
1771 result = "uniform_bvec4";
1772 else if (location == m_po_dmat2_arr_uniform_location)
1773 result = "uniform_dmat2_arr";
1774 else if (location == m_po_dmat2_uniform_location)
1775 result = "uniform_dmat2";
1776 else if (location == m_po_dmat2x3_arr_uniform_location)
1777 result = "uniform_dmat2x3_arr";
1778 else if (location == m_po_dmat2x3_uniform_location)
1779 result = "uniform_dmat2x3";
1780 else if (location == m_po_dmat2x4_arr_uniform_location)
1781 result = "uniform_dmat2x4_arr";
1782 else if (location == m_po_dmat2x4_uniform_location)
1783 result = "uniform_dmat2x4";
1784 else if (location == m_po_dmat3_arr_uniform_location)
1785 result = "uniform_dmat3_arr";
1786 else if (location == m_po_dmat3_uniform_location)
1787 result = "uniform_dmat3";
1788 else if (location == m_po_dmat3x2_arr_uniform_location)
1789 result = "uniform_dmat3x2_arr";
1790 else if (location == m_po_dmat3x2_uniform_location)
1791 result = "uniform_dmat3x2";
1792 else if (location == m_po_dmat3x4_arr_uniform_location)
1793 result = "uniform_dmat3x4_arr";
1794 else if (location == m_po_dmat3x4_uniform_location)
1795 result = "uniform_dmat3x4";
1796 else if (location == m_po_dmat4_arr_uniform_location)
1797 result = "uniform_dmat4_arr";
1798 else if (location == m_po_dmat4_uniform_location)
1799 result = "uniform_dmat4";
1800 else if (location == m_po_dmat4x2_arr_uniform_location)
1801 result = "uniform_dmat4x2_arr";
1802 else if (location == m_po_dmat4x2_uniform_location)
1803 result = "uniform_dmat4x2";
1804 else if (location == m_po_dmat4x3_arr_uniform_location)
1805 result = "uniform_dmat4x3_arr";
1806 else if (location == m_po_dmat4x3_uniform_location)
1807 result = "uniform_dmat4x3";
1808 else if (location == m_po_double_arr_uniform_location)
1809 result = "uniform_double_arr";
1810 else if (location == m_po_double_uniform_location)
1811 result = "uniform_double";
1812 else if (location == m_po_dvec2_arr_uniform_location)
1813 result = "uniform_dvec2_arr";
1814 else if (location == m_po_dvec2_uniform_location)
1815 result = "uniform_dvec2";
1816 else if (location == m_po_dvec3_arr_uniform_location)
1817 result = "uniform_dvec3_arr";
1818 else if (location == m_po_dvec3_uniform_location)
1819 result = "uniform_dvec3";
1820 else if (location == m_po_dvec4_arr_uniform_location)
1821 result = "uniform_dvec4_arr";
1822 else if (location == m_po_dvec4_uniform_location)
1823 result = "uniform_dvec4";
1824 else if (location == m_po_float_arr_uniform_location)
1825 result = "uniform_float_arr";
1826 else if (location == m_po_float_uniform_location)
1827 result = "uniform_float";
1828 else if (location == m_po_int_arr_uniform_location)
1829 result = "uniform_int_arr";
1830 else if (location == m_po_int_uniform_location)
1831 result = "uniform_int";
1832 else if (location == m_po_ivec2_arr_uniform_location)
1833 result = "uniform_ivec2_arr";
1834 else if (location == m_po_ivec2_uniform_location)
1835 result = "uniform_ivec2";
1836 else if (location == m_po_ivec3_arr_uniform_location)
1837 result = "uniform_ivec3_arr";
1838 else if (location == m_po_ivec3_uniform_location)
1839 result = "uniform_ivec3";
1840 else if (location == m_po_ivec4_arr_uniform_location)
1841 result = "uniform_ivec4_arr";
1842 else if (location == m_po_ivec4_uniform_location)
1843 result = "uniform_ivec4";
1844 else if (location == m_po_uint_arr_uniform_location)
1845 result = "uniform_uint_arr";
1846 else if (location == m_po_uint_uniform_location)
1847 result = "uniform_uint";
1848 else if (location == m_po_uvec2_arr_uniform_location)
1849 result = "uniform_uvec2_arr";
1850 else if (location == m_po_uvec2_uniform_location)
1851 result = "uniform_uvec2";
1852 else if (location == m_po_uvec3_arr_uniform_location)
1853 result = "uniform_uvec3_arr";
1854 else if (location == m_po_uvec3_uniform_location)
1855 result = "uniform_uvec3";
1856 else if (location == m_po_uvec4_arr_uniform_location)
1857 result = "uniform_uvec4_arr";
1858 else if (location == m_po_uvec4_uniform_location)
1859 result = "uniform_uvec4";
1860 else if (location == m_po_vec2_arr_uniform_location)
1861 result = "uniform_vec2_arr";
1862 else if (location == m_po_vec2_uniform_location)
1863 result = "uniform_vec2";
1864 else if (location == m_po_vec3_arr_uniform_location)
1865 result = "uniform_vec3_arr";
1866 else if (location == m_po_vec3_uniform_location)
1867 result = "uniform_vec3";
1868 else if (location == m_po_vec4_arr_uniform_location)
1869 result = "uniform_vec4_arr";
1870 else if (location == m_po_vec4_uniform_location)
1871 result = "uniform_vec4";
1876 /** Initializes all GL objects required to run the test. Also extracts locations of all
1877 * uniforms used by the test.
1879 * This function can throw a TestError exception if the implementation misbehaves.
1881 void GPUShaderFP64Test1::initTest()
1883 glw::GLint compile_status = GL_FALSE;
1884 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1885 glw::GLint link_status = GL_FALSE;
1887 /* Set up a program object using all new double-precision types */
1888 const char* vs_body =
1891 "uniform bool uniform_bool;\n"
1892 "uniform bvec2 uniform_bvec2;\n"
1893 "uniform bvec3 uniform_bvec3;\n"
1894 "uniform bvec4 uniform_bvec4;\n"
1895 "uniform dmat2 uniform_dmat2;\n"
1896 "uniform dmat2x3 uniform_dmat2x3;\n"
1897 "uniform dmat2x4 uniform_dmat2x4;\n"
1898 "uniform dmat3 uniform_dmat3;\n"
1899 "uniform dmat3x2 uniform_dmat3x2;\n"
1900 "uniform dmat3x4 uniform_dmat3x4;\n"
1901 "uniform dmat4 uniform_dmat4;\n"
1902 "uniform dmat4x2 uniform_dmat4x2;\n"
1903 "uniform dmat4x3 uniform_dmat4x3;\n"
1904 "uniform double uniform_double;\n"
1905 "uniform dvec2 uniform_dvec2;\n"
1906 "uniform dvec3 uniform_dvec3;\n"
1907 "uniform dvec4 uniform_dvec4;\n"
1908 "uniform float uniform_float;\n"
1909 "uniform int uniform_int;\n"
1910 "uniform ivec2 uniform_ivec2;\n"
1911 "uniform ivec3 uniform_ivec3;\n"
1912 "uniform ivec4 uniform_ivec4;\n"
1913 "uniform sampler2D uniform_sampler;\n"
1914 "uniform uint uniform_uint;\n"
1915 "uniform uvec2 uniform_uvec2;\n"
1916 "uniform uvec3 uniform_uvec3;\n"
1917 "uniform uvec4 uniform_uvec4;\n"
1918 "uniform vec2 uniform_vec2;\n"
1919 "uniform vec3 uniform_vec3;\n"
1920 "uniform vec4 uniform_vec4;\n"
1921 "uniform bool uniform_bool_arr [2];\n"
1922 "uniform bvec2 uniform_bvec2_arr [2];\n"
1923 "uniform bvec3 uniform_bvec3_arr [2];\n"
1924 "uniform bvec4 uniform_bvec4_arr [2];\n"
1925 "uniform dmat2 uniform_dmat2_arr [2];\n"
1926 "uniform dmat2x3 uniform_dmat2x3_arr[2];\n"
1927 "uniform dmat2x4 uniform_dmat2x4_arr[2];\n"
1928 "uniform dmat3 uniform_dmat3_arr [2];\n"
1929 "uniform dmat3x2 uniform_dmat3x2_arr[2];\n"
1930 "uniform dmat3x4 uniform_dmat3x4_arr[2];\n"
1931 "uniform dmat4 uniform_dmat4_arr [2];\n"
1932 "uniform dmat4x2 uniform_dmat4x2_arr[2];\n"
1933 "uniform dmat4x3 uniform_dmat4x3_arr[2];\n"
1934 "uniform double uniform_double_arr [2];\n"
1935 "uniform dvec2 uniform_dvec2_arr [2];\n"
1936 "uniform dvec3 uniform_dvec3_arr [2];\n"
1937 "uniform dvec4 uniform_dvec4_arr [2];\n"
1938 "uniform float uniform_float_arr [2];\n"
1939 "uniform int uniform_int_arr [2];\n"
1940 "uniform ivec2 uniform_ivec2_arr [2];\n"
1941 "uniform ivec3 uniform_ivec3_arr [2];\n"
1942 "uniform ivec4 uniform_ivec4_arr [2];\n"
1943 "uniform uint uniform_uint_arr [2];\n"
1944 "uniform uvec2 uniform_uvec2_arr [2];\n"
1945 "uniform uvec3 uniform_uvec3_arr [2];\n"
1946 "uniform uvec4 uniform_uvec4_arr [2];\n"
1947 "uniform vec2 uniform_vec2_arr [2];\n"
1948 "uniform vec3 uniform_vec3_arr [2];\n"
1949 "uniform vec4 uniform_vec4_arr [2];\n"
1953 " gl_Position = vec4(0) + texture(uniform_sampler, vec2(0) );\n"
1955 " if (uniform_bool && uniform_bvec2.y && uniform_bvec3.z && uniform_bvec4.w &&\n"
1956 " uniform_bool_arr[1] && uniform_bvec2_arr[1].y && uniform_bvec3_arr[1].z && uniform_bvec4_arr[1].w)\n"
1958 " double sum = uniform_dmat2 [0].x + uniform_dmat2x3 [0].x + uniform_dmat2x4 [0].x +\n"
1959 " uniform_dmat3 [0].x + uniform_dmat3x2 [0].x + uniform_dmat3x4 [0].x +\n"
1960 " uniform_dmat4 [0].x + uniform_dmat4x2 [0].x + uniform_dmat4x3 [0].x +\n"
1961 " uniform_dmat2_arr[0][0].x + uniform_dmat2x3_arr[0][0].x + uniform_dmat2x4_arr[0][0].x +\n"
1962 " uniform_dmat3_arr[0][0].x + uniform_dmat3x2_arr[0][0].x + uniform_dmat3x4_arr[0][0].x +\n"
1963 " uniform_dmat4_arr[0][0].x + uniform_dmat4x2_arr[0][0].x + uniform_dmat4x3_arr[0][0].x +\n"
1964 " uniform_double + uniform_double_arr [0] +\n"
1965 " uniform_dvec2.x + uniform_dvec3.x + uniform_dvec4.x +\n"
1966 " uniform_dvec2_arr[0].x + uniform_dvec3_arr[0].x + uniform_dvec4_arr[0].x;\n"
1967 " int sum2 = uniform_int + uniform_ivec2.x + uniform_ivec3.x +\n"
1968 " uniform_ivec4.x + uniform_ivec2_arr[0].x + uniform_ivec3_arr[0].x +\n"
1969 " uniform_ivec4_arr[0].x + uniform_int_arr[0];\n"
1970 " uint sum3 = uniform_uint + uniform_uvec2.x + uniform_uvec3.x +\n"
1971 " uniform_uvec4.x + uniform_uint_arr[0] + uniform_uvec2_arr[0].x +\n"
1972 " uniform_uvec3_arr[0].x + uniform_uvec4_arr[0].x;\n"
1973 " float sum4 = uniform_float + uniform_float_arr[0] + \n"
1974 " uniform_vec2.x + uniform_vec2_arr[0].x + \n"
1975 " uniform_vec3.x + uniform_vec3_arr[0].x + \n"
1976 " uniform_vec4.x + uniform_vec4_arr[0].x;\n"
1978 " if (sum * sum4 > intBitsToFloat(sum2) * uintBitsToFloat(sum3) )\n"
1980 " gl_Position = vec4(1);\n"
1985 m_po_id = gl.createProgram();
1986 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1988 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1989 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
1991 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
1992 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
1994 gl.compileShader(m_vs_id);
1995 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
1997 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
1998 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
2000 if (compile_status != GL_TRUE)
2002 TCU_FAIL("Shader compilation failed.");
2005 gl.attachShader(m_po_id, m_vs_id);
2006 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
2008 gl.linkProgram(m_po_id);
2009 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
2011 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
2012 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
2014 if (link_status != GL_TRUE)
2016 TCU_FAIL("Program linking failed.");
2019 m_po_bool_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bool_arr[0]");
2020 m_po_bool_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bool");
2021 m_po_bvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec2_arr[0]");
2022 m_po_bvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec2");
2023 m_po_bvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec3_arr[0]");
2024 m_po_bvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec3");
2025 m_po_bvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec4_arr[0]");
2026 m_po_bvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec4");
2027 m_po_dmat2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2_arr[0]");
2028 m_po_dmat2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2");
2029 m_po_dmat2x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3_arr[0]");
2030 m_po_dmat2x3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3");
2031 m_po_dmat2x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4_arr[0]");
2032 m_po_dmat2x4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4");
2033 m_po_dmat3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3_arr[0]");
2034 m_po_dmat3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3");
2035 m_po_dmat3x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2_arr[0]");
2036 m_po_dmat3x2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2");
2037 m_po_dmat3x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4_arr[0]");
2038 m_po_dmat3x4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4");
2039 m_po_dmat4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4_arr[0]");
2040 m_po_dmat4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4");
2041 m_po_dmat4x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2_arr[0]");
2042 m_po_dmat4x2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2");
2043 m_po_dmat4x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3_arr[0]");
2044 m_po_dmat4x3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3");
2045 m_po_double_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_double_arr[0]");
2046 m_po_double_uniform_location = gl.getUniformLocation(m_po_id, "uniform_double");
2047 m_po_dvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec2_arr[0]");
2048 m_po_dvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec2");
2049 m_po_dvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec3_arr[0]");
2050 m_po_dvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec3");
2051 m_po_dvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec4_arr[0]");
2052 m_po_dvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec4");
2053 m_po_float_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_float_arr[0]");
2054 m_po_float_uniform_location = gl.getUniformLocation(m_po_id, "uniform_float");
2055 m_po_int_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_int_arr[0]");
2056 m_po_int_uniform_location = gl.getUniformLocation(m_po_id, "uniform_int");
2057 m_po_ivec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec2_arr[0]");
2058 m_po_ivec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec2");
2059 m_po_ivec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec3_arr[0]");
2060 m_po_ivec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec3");
2061 m_po_ivec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec4_arr[0]");
2062 m_po_ivec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec4");
2063 m_po_sampler_uniform_location = gl.getUniformLocation(m_po_id, "uniform_sampler");
2064 m_po_uint_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uint_arr[0]");
2065 m_po_uint_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uint");
2066 m_po_uvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec2_arr[0]");
2067 m_po_uvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec2");
2068 m_po_uvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec3_arr[0]");
2069 m_po_uvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec3");
2070 m_po_uvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec4_arr[0]");
2071 m_po_uvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec4");
2072 m_po_vec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec2_arr[0]");
2073 m_po_vec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec2");
2074 m_po_vec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec3_arr[0]");
2075 m_po_vec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec3");
2076 m_po_vec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec4_arr[0]");
2077 m_po_vec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec4");
2078 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed.");
2080 if (m_po_bool_arr_uniform_location == -1 || m_po_bool_uniform_location == -1 ||
2081 m_po_bvec2_arr_uniform_location == -1 || m_po_bvec2_uniform_location == -1 ||
2082 m_po_bvec3_arr_uniform_location == -1 || m_po_bvec3_uniform_location == -1 ||
2083 m_po_bvec4_arr_uniform_location == -1 || m_po_bvec4_uniform_location == -1 ||
2084 m_po_dmat2_arr_uniform_location == -1 || m_po_dmat2_uniform_location == -1 ||
2085 m_po_dmat2x3_arr_uniform_location == -1 || m_po_dmat2x3_uniform_location == -1 ||
2086 m_po_dmat2x4_arr_uniform_location == -1 || m_po_dmat2x4_uniform_location == -1 ||
2087 m_po_dmat3_arr_uniform_location == -1 || m_po_dmat3_uniform_location == -1 ||
2088 m_po_dmat3x2_arr_uniform_location == -1 || m_po_dmat3x2_uniform_location == -1 ||
2089 m_po_dmat3x4_arr_uniform_location == -1 || m_po_dmat3x4_uniform_location == -1 ||
2090 m_po_dmat4_arr_uniform_location == -1 || m_po_dmat4_uniform_location == -1 ||
2091 m_po_dmat4x2_arr_uniform_location == -1 || m_po_dmat4x2_uniform_location == -1 ||
2092 m_po_dmat4x3_arr_uniform_location == -1 || m_po_dmat4x3_uniform_location == -1 ||
2093 m_po_double_arr_uniform_location == -1 || m_po_double_uniform_location == -1 ||
2094 m_po_dvec2_arr_uniform_location == -1 || m_po_dvec2_uniform_location == -1 ||
2095 m_po_dvec3_arr_uniform_location == -1 || m_po_dvec3_uniform_location == -1 ||
2096 m_po_dvec4_arr_uniform_location == -1 || m_po_dvec4_uniform_location == -1 ||
2097 m_po_float_arr_uniform_location == -1 || m_po_float_uniform_location == -1 ||
2098 m_po_int_arr_uniform_location == -1 || m_po_int_uniform_location == -1 ||
2099 m_po_ivec2_arr_uniform_location == -1 || m_po_ivec2_uniform_location == -1 ||
2100 m_po_ivec3_arr_uniform_location == -1 || m_po_ivec3_uniform_location == -1 ||
2101 m_po_ivec4_arr_uniform_location == -1 || m_po_ivec4_uniform_location == -1 ||
2102 m_po_sampler_uniform_location == -1 || m_po_uint_arr_uniform_location == -1 ||
2103 m_po_uint_uniform_location == -1 || m_po_uvec2_arr_uniform_location == -1 ||
2104 m_po_uvec2_uniform_location == -1 || m_po_uvec3_arr_uniform_location == -1 ||
2105 m_po_uvec3_uniform_location == -1 || m_po_uvec4_arr_uniform_location == -1 ||
2106 m_po_uvec4_uniform_location == -1 || m_po_vec2_arr_uniform_location == -1 || m_po_vec2_uniform_location == -1 ||
2107 m_po_vec3_arr_uniform_location == -1 || m_po_vec3_uniform_location == -1 ||
2108 m_po_vec4_arr_uniform_location == -1 || m_po_vec4_uniform_location == -1)
2110 TCU_FAIL("At last one of the required uniforms is considered inactive.");
2114 /** Tells wheter uniform at user-specified location represents a double-precision
2117 * @param uniform_location Location of the uniform to use for the query.
2119 * @return Requested information.
2121 bool GPUShaderFP64Test1::isMatrixUniform(glw::GLint uniform_location)
2123 return (uniform_location == m_po_dmat2_uniform_location || uniform_location == m_po_dmat2x3_uniform_location ||
2124 uniform_location == m_po_dmat2x4_uniform_location || uniform_location == m_po_dmat3_uniform_location ||
2125 uniform_location == m_po_dmat3x2_uniform_location || uniform_location == m_po_dmat3x4_uniform_location ||
2126 uniform_location == m_po_dmat4_uniform_location || uniform_location == m_po_dmat4x2_uniform_location ||
2127 uniform_location == m_po_dmat4x3_uniform_location);
2130 /** Tells whether user-specified uniform function corresponds to one of the
2131 * functions in glUniformMatrix*() class.
2133 * @param func Uniform function enum to use for the query.
2135 * @return true if the specified enum represents one of the glUniformMatrix*() functions,
2138 bool GPUShaderFP64Test1::isMatrixUniformFunction(_uniform_function func)
2140 return (func == UNIFORM_FUNCTION_MATRIX2DV || func == UNIFORM_FUNCTION_MATRIX2X3DV ||
2141 func == UNIFORM_FUNCTION_MATRIX2X4DV || func == UNIFORM_FUNCTION_MATRIX3DV ||
2142 func == UNIFORM_FUNCTION_MATRIX3X2DV || func == UNIFORM_FUNCTION_MATRIX3X4DV ||
2143 func == UNIFORM_FUNCTION_MATRIX4DV || func == UNIFORM_FUNCTION_MATRIX4X2DV ||
2144 func == UNIFORM_FUNCTION_MATRIX4X3DV);
2147 /** Executes test iteration.
2149 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2151 tcu::TestNode::IterateResult GPUShaderFP64Test1::iterate()
2153 /* Do not execute the test if GL_ARB_texture_view is not supported */
2154 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
2156 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
2159 /* Initialize all ES objects required to run all the checks */
2162 /* Make sure GL_INVALID_OPERATION is generated by glUniform*() and
2163 * glUniformMatrix*() functions if there is no current program object.
2165 m_has_test_passed &= verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO();
2167 /* Make sure GL_INVALID_OPERATION is generated by glUniform*() if
2168 * the size of the uniform variable declared in the shader does not
2169 * match the size indicated by the command.
2171 m_has_test_passed &= verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions();
2173 /* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
2174 * glUniformMatrix*() are used to load a uniform variable of type
2175 * bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4,
2176 * unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array
2179 m_has_test_passed &= verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions();
2181 /* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
2182 * glUniformMatrix*() are used to load incompatible double-typed
2183 * uniforms, as presented below:
2185 * I. double-typed uniform configured by glUniform2d();
2186 * II. double-typed uniform configured by glUniform3d();
2187 * III. double-typed uniform configured by glUniform4d();
2188 * IV. double-typed uniform configured by glUniformMatrix*();
2189 * V. dvec2-typed uniform configured by glUniform1d();
2190 * VI. dvec2-typed uniform configured by glUniform3d();
2191 * VII. dvec2-typed uniform configured by glUniform4d();
2192 * VIII. dvec2-typed uniform configured by glUniformMatrix*();
2197 m_has_test_passed &= verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions();
2199 /* Make sure GL_INVALID_OPERATION is generated if <location> of
2200 * glUniform*() and glUniformMatrix*() is an invalid uniform
2201 * location for the current program object and location is not
2204 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation();
2206 /* Make sure GL_INVALID_VALUE is generated if <count> of
2207 * glUniform*() (*dv() functions only) and glUniformMatrix*() is
2210 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount();
2212 /* Make sure GL_INVALID_OPERATION is generated if <count> of
2213 * glUniform*() (*dv() functions only) and glUniformMatrix*() is
2214 * greater than 1 and the indicated uniform variable is not an
2217 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount();
2219 /* Make sure GL_INVALID_OPERATION is generated if a sampler is
2220 * loaded by glUniform*() and glUniformMatrix*().
2222 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers();
2224 /* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
2225 * glUniformMatrix*() is used to load values for uniforms of
2228 m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans();
2230 if (m_has_test_passed)
2232 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2236 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2242 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
2243 * glUniformMatrix*dv() functions is used to load a boolean uniform.
2245 * @return true if the implementation was found to behave as expected, false otherwise.
2247 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans()
2249 const double double_data[] = {
2250 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
2252 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2254 glw::GLint uniform_locations[] = { m_po_bool_arr_uniform_location, m_po_bool_uniform_location,
2255 m_po_bvec2_arr_uniform_location, m_po_bvec2_uniform_location,
2256 m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location,
2257 m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location };
2258 const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]);
2260 for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
2261 ++n_uniform_function)
2263 const _uniform_function uniform_function = (_uniform_function)n_uniform_function;
2265 for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
2267 const glw::GLint uniform_location = uniform_locations[n_uniform_location];
2269 switch (uniform_function)
2271 case UNIFORM_FUNCTION_1D:
2272 gl.uniform1d(uniform_location, 0.0);
2274 case UNIFORM_FUNCTION_2D:
2275 gl.uniform2d(uniform_location, 0.0, 1.0);
2277 case UNIFORM_FUNCTION_3D:
2278 gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
2280 case UNIFORM_FUNCTION_4D:
2281 gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
2284 case UNIFORM_FUNCTION_1DV:
2285 gl.uniform1dv(uniform_location, 1 /* count */, double_data);
2287 case UNIFORM_FUNCTION_2DV:
2288 gl.uniform2dv(uniform_location, 1 /* count */, double_data);
2290 case UNIFORM_FUNCTION_3DV:
2291 gl.uniform3dv(uniform_location, 1 /* count */, double_data);
2293 case UNIFORM_FUNCTION_4DV:
2294 gl.uniform4dv(uniform_location, 1 /* count */, double_data);
2297 case UNIFORM_FUNCTION_MATRIX2DV:
2298 gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2300 case UNIFORM_FUNCTION_MATRIX2X3DV:
2301 gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2303 case UNIFORM_FUNCTION_MATRIX2X4DV:
2304 gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2306 case UNIFORM_FUNCTION_MATRIX3DV:
2307 gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2309 case UNIFORM_FUNCTION_MATRIX3X2DV:
2310 gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2312 case UNIFORM_FUNCTION_MATRIX3X4DV:
2313 gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2315 case UNIFORM_FUNCTION_MATRIX4DV:
2316 gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2318 case UNIFORM_FUNCTION_MATRIX4X2DV:
2319 gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2321 case UNIFORM_FUNCTION_MATRIX4X3DV:
2322 gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2327 TCU_FAIL("Unrecognized uniform function");
2331 /* Make sure GL_INVALID_OPERATION was generated by the call */
2332 const glw::GLenum error_code = gl.getError();
2334 if (error_code != GL_INVALID_OPERATION)
2336 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
2337 << "() did not generate an error"
2338 " when applied against a boolean uniform."
2339 << tcu::TestLog::EndMessage;
2343 } /* for (all bool uniforms) */
2344 } /* for (all uniform functions) */
2349 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
2350 * glUniformMatrix*dv() functions is used to load a sampler2D uniform.
2352 * @return true if the implementation was found to behave as expected, false otherwise.
2354 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers()
2356 const double double_data[] = {
2357 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
2359 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2362 for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
2363 ++n_uniform_function)
2365 _uniform_function uniform_function = (_uniform_function)n_uniform_function;
2367 switch (uniform_function)
2369 case UNIFORM_FUNCTION_1D:
2370 gl.uniform1d(m_po_sampler_uniform_location, 0.0);
2372 case UNIFORM_FUNCTION_2D:
2373 gl.uniform2d(m_po_sampler_uniform_location, 0.0, 1.0);
2375 case UNIFORM_FUNCTION_3D:
2376 gl.uniform3d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0);
2378 case UNIFORM_FUNCTION_4D:
2379 gl.uniform4d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0, 3.0);
2382 case UNIFORM_FUNCTION_1DV:
2383 gl.uniform1dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
2385 case UNIFORM_FUNCTION_2DV:
2386 gl.uniform2dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
2388 case UNIFORM_FUNCTION_3DV:
2389 gl.uniform3dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
2391 case UNIFORM_FUNCTION_4DV:
2392 gl.uniform4dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
2395 case UNIFORM_FUNCTION_MATRIX2DV:
2396 gl.uniformMatrix2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2398 case UNIFORM_FUNCTION_MATRIX2X3DV:
2399 gl.uniformMatrix2x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2401 case UNIFORM_FUNCTION_MATRIX2X4DV:
2402 gl.uniformMatrix2x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2404 case UNIFORM_FUNCTION_MATRIX3DV:
2405 gl.uniformMatrix3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2407 case UNIFORM_FUNCTION_MATRIX3X2DV:
2408 gl.uniformMatrix3x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2410 case UNIFORM_FUNCTION_MATRIX3X4DV:
2411 gl.uniformMatrix3x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2413 case UNIFORM_FUNCTION_MATRIX4DV:
2414 gl.uniformMatrix4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2416 case UNIFORM_FUNCTION_MATRIX4X2DV:
2417 gl.uniformMatrix4x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2419 case UNIFORM_FUNCTION_MATRIX4X3DV:
2420 gl.uniformMatrix4x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2425 TCU_FAIL("Unrecognized uniform function");
2429 /* Make sure GL_INVALID_OPERATION was generated by the call */
2430 const glw::GLenum error_code = gl.getError();
2432 if (error_code != GL_INVALID_OPERATION)
2434 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
2435 << "() did not generate an error"
2436 " when applied against a sampler uniform."
2437 << tcu::TestLog::EndMessage;
2441 } /* for (all uniform functions) */
2446 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*dv() or
2447 * glUniformMatrix*dv() functions is used to load a compatible uniform using an
2448 * invalid <count> argument.
2450 * @return true if the implementation was found to behave as expected, false otherwise.
2452 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount()
2454 const glw::GLdouble double_values[16] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
2455 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
2456 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2458 const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV, UNIFORM_FUNCTION_2DV,
2459 UNIFORM_FUNCTION_3DV, UNIFORM_FUNCTION_4DV,
2460 UNIFORM_FUNCTION_MATRIX2DV, UNIFORM_FUNCTION_MATRIX2X3DV,
2461 UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
2462 UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
2463 UNIFORM_FUNCTION_MATRIX4DV, UNIFORM_FUNCTION_MATRIX4X2DV,
2464 UNIFORM_FUNCTION_MATRIX4X3DV };
2465 const glw::GLint uniforms[] = {
2466 m_po_bool_uniform_location, m_po_bvec2_uniform_location, m_po_bvec3_uniform_location,
2467 m_po_bvec4_uniform_location, m_po_dmat2_uniform_location, m_po_dmat2x3_uniform_location,
2468 m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location, m_po_dmat3x2_uniform_location,
2469 m_po_dmat3x4_uniform_location, m_po_dmat4_uniform_location, m_po_dmat4x2_uniform_location,
2470 m_po_dmat4x3_uniform_location, m_po_double_uniform_location, m_po_dvec2_uniform_location,
2471 m_po_dvec3_uniform_location, m_po_dvec4_uniform_location, m_po_float_uniform_location,
2472 m_po_int_uniform_location, m_po_ivec2_uniform_location, m_po_ivec3_uniform_location,
2473 m_po_ivec4_uniform_location, m_po_uint_uniform_location, m_po_uvec2_uniform_location,
2474 m_po_uvec3_uniform_location, m_po_uvec4_uniform_location, m_po_vec2_uniform_location,
2475 m_po_vec3_uniform_location, m_po_vec4_uniform_location
2478 const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);
2479 const unsigned int n_uniforms = sizeof(uniforms) / sizeof(uniforms[0]);
2481 for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
2483 _uniform_function uniform_function = uniform_functions[n_uniform_function];
2485 for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
2487 glw::GLint uniform_location = uniforms[n_uniform];
2489 /* Make sure we only use glUniformMatrix*() functions with matrix uniforms,
2490 * and glUniform*() functions with vector uniforms.
2492 bool is_matrix_uniform = isMatrixUniform(uniform_location);
2494 if (((false == is_matrix_uniform) && (true == isMatrixUniformFunction(uniform_function))) ||
2495 ((true == is_matrix_uniform) && (false == isMatrixUniformFunction(uniform_function))))
2500 /* Issue the call with an invalid <count> argument */
2501 switch (uniform_function)
2503 case UNIFORM_FUNCTION_1DV:
2504 gl.uniform1dv(uniform_location, 2, double_values);
2506 case UNIFORM_FUNCTION_2DV:
2507 gl.uniform2dv(uniform_location, 2, double_values);
2509 case UNIFORM_FUNCTION_3DV:
2510 gl.uniform3dv(uniform_location, 2, double_values);
2512 case UNIFORM_FUNCTION_4DV:
2513 gl.uniform4dv(uniform_location, 2, double_values);
2515 case UNIFORM_FUNCTION_MATRIX2DV:
2516 gl.uniformMatrix2dv(uniform_location, 2, GL_FALSE, double_values);
2518 case UNIFORM_FUNCTION_MATRIX2X3DV:
2519 gl.uniformMatrix2x3dv(uniform_location, 2, GL_FALSE, double_values);
2521 case UNIFORM_FUNCTION_MATRIX2X4DV:
2522 gl.uniformMatrix2x4dv(uniform_location, 2, GL_FALSE, double_values);
2524 case UNIFORM_FUNCTION_MATRIX3DV:
2525 gl.uniformMatrix3dv(uniform_location, 2, GL_FALSE, double_values);
2527 case UNIFORM_FUNCTION_MATRIX3X2DV:
2528 gl.uniformMatrix3x2dv(uniform_location, 2, GL_FALSE, double_values);
2530 case UNIFORM_FUNCTION_MATRIX3X4DV:
2531 gl.uniformMatrix3x4dv(uniform_location, 2, GL_FALSE, double_values);
2533 case UNIFORM_FUNCTION_MATRIX4DV:
2534 gl.uniformMatrix4dv(uniform_location, 2, GL_FALSE, double_values);
2536 case UNIFORM_FUNCTION_MATRIX4X2DV:
2537 gl.uniformMatrix4x2dv(uniform_location, 2, GL_FALSE, double_values);
2539 case UNIFORM_FUNCTION_MATRIX4X3DV:
2540 gl.uniformMatrix4x3dv(uniform_location, 2, GL_FALSE, double_values);
2545 TCU_FAIL("Unrecognized uniform function");
2547 } /* switch (uniform_function) */
2549 /* Make sure GL_INVALID_VALUE was generated */
2550 glw::GLenum error_code = gl.getError();
2552 if (error_code != GL_INVALID_OPERATION)
2554 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
2556 "was called with an invalid count argument but did not generate a "
2557 "GL_INVALID_OPERATION error"
2558 << tcu::TestLog::EndMessage;
2562 } /* for (all non-arrayed uniforms) */
2563 } /* for (all uniform functions) */
2568 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
2569 * glUniformMatrix*dv() functions is used to load an uniform at an invalid location.
2571 * @return true if the implementation was found to behave as expected, false otherwise.
2573 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation()
2575 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2578 /* Find the largest valid uniform location */
2579 const glw::GLint uniform_locations[] = {
2580 m_po_bool_arr_uniform_location, m_po_bool_uniform_location, m_po_bvec2_arr_uniform_location,
2581 m_po_bvec2_uniform_location, m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location,
2582 m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location, m_po_dmat2_arr_uniform_location,
2583 m_po_dmat2_uniform_location, m_po_dmat2x3_arr_uniform_location, m_po_dmat2x3_uniform_location,
2584 m_po_dmat2x4_arr_uniform_location, m_po_dmat2x4_uniform_location, m_po_dmat3_arr_uniform_location,
2585 m_po_dmat3_uniform_location, m_po_dmat3x2_arr_uniform_location, m_po_dmat3x2_uniform_location,
2586 m_po_dmat3x4_arr_uniform_location, m_po_dmat3x4_uniform_location, m_po_dmat4_arr_uniform_location,
2587 m_po_dmat4_uniform_location, m_po_dmat4x2_arr_uniform_location, m_po_dmat4x2_uniform_location,
2588 m_po_dmat4x3_arr_uniform_location, m_po_dmat4x3_uniform_location, m_po_double_arr_uniform_location,
2589 m_po_double_uniform_location, m_po_dvec2_arr_uniform_location, m_po_dvec2_uniform_location,
2590 m_po_dvec3_arr_uniform_location, m_po_dvec3_uniform_location, m_po_dvec4_arr_uniform_location,
2591 m_po_dvec4_uniform_location, m_po_float_arr_uniform_location, m_po_float_uniform_location,
2592 m_po_int_arr_uniform_location, m_po_int_uniform_location, m_po_ivec2_arr_uniform_location,
2593 m_po_ivec2_uniform_location, m_po_ivec3_arr_uniform_location, m_po_ivec3_uniform_location,
2594 m_po_ivec4_arr_uniform_location, m_po_ivec4_uniform_location, m_po_uint_arr_uniform_location,
2595 m_po_uint_uniform_location, m_po_uvec2_arr_uniform_location, m_po_uvec2_uniform_location,
2596 m_po_uvec3_arr_uniform_location, m_po_uvec3_uniform_location, m_po_uvec4_arr_uniform_location,
2597 m_po_uvec4_uniform_location, m_po_vec2_arr_uniform_location, m_po_vec2_uniform_location,
2598 m_po_vec3_arr_uniform_location, m_po_vec3_uniform_location, m_po_vec4_arr_uniform_location,
2599 m_po_vec4_uniform_location
2601 const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]);
2602 glw::GLint valid_uniform_location = -1;
2604 for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
2606 glw::GLint uniform_location = uniform_locations[n_uniform_location];
2608 if (uniform_location > valid_uniform_location)
2610 valid_uniform_location = uniform_location;
2612 } /* for (all uniform locations) */
2614 /* Iterate through all uniform functions and make sure GL_INVALID_OPERATION error is always generated
2615 * for invalid uniform location that is != -1
2617 const double double_data[] = {
2618 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
2620 const glw::GLint invalid_uniform_location = valid_uniform_location + 1;
2622 for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
2623 ++n_uniform_function)
2625 _uniform_function uniform_function = (_uniform_function)n_uniform_function;
2627 switch (uniform_function)
2629 case UNIFORM_FUNCTION_1D:
2630 gl.uniform1d(invalid_uniform_location, 0.0);
2632 case UNIFORM_FUNCTION_2D:
2633 gl.uniform2d(invalid_uniform_location, 0.0, 1.0);
2635 case UNIFORM_FUNCTION_3D:
2636 gl.uniform3d(invalid_uniform_location, 0.0, 1.0, 2.0);
2638 case UNIFORM_FUNCTION_4D:
2639 gl.uniform4d(invalid_uniform_location, 0.0, 1.0, 2.0, 3.0);
2642 case UNIFORM_FUNCTION_1DV:
2643 gl.uniform1dv(invalid_uniform_location, 1 /* count */, double_data);
2645 case UNIFORM_FUNCTION_2DV:
2646 gl.uniform2dv(invalid_uniform_location, 1 /* count */, double_data);
2648 case UNIFORM_FUNCTION_3DV:
2649 gl.uniform3dv(invalid_uniform_location, 1 /* count */, double_data);
2651 case UNIFORM_FUNCTION_4DV:
2652 gl.uniform4dv(invalid_uniform_location, 1 /* count */, double_data);
2655 case UNIFORM_FUNCTION_MATRIX2DV:
2656 gl.uniformMatrix2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2658 case UNIFORM_FUNCTION_MATRIX2X3DV:
2659 gl.uniformMatrix2x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2661 case UNIFORM_FUNCTION_MATRIX2X4DV:
2662 gl.uniformMatrix2x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2664 case UNIFORM_FUNCTION_MATRIX3DV:
2665 gl.uniformMatrix3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2667 case UNIFORM_FUNCTION_MATRIX3X2DV:
2668 gl.uniformMatrix3x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2670 case UNIFORM_FUNCTION_MATRIX3X4DV:
2671 gl.uniformMatrix3x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2673 case UNIFORM_FUNCTION_MATRIX4DV:
2674 gl.uniformMatrix4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2676 case UNIFORM_FUNCTION_MATRIX4X2DV:
2677 gl.uniformMatrix4x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2679 case UNIFORM_FUNCTION_MATRIX4X3DV:
2680 gl.uniformMatrix4x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
2685 TCU_FAIL("Unrecognized uniform function");
2689 const glw::GLenum error_code = gl.getError();
2691 if (error_code != GL_INVALID_OPERATION)
2693 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
2694 << "() did not generate an error"
2695 " when passed an invalid uniform location different from -1."
2696 << tcu::TestLog::EndMessage;
2700 } /* for (all uniform functions) */
2705 /** Verifies GL_INVALID_VALUE is generated if any of the glUniform*dv() or
2706 * glUniformMatrix*dv() functions is used to load a compatible uniform using an
2707 * invalid <count> argument of -1.
2709 * @return true if the implementation was found to behave as expected, false otherwise.
2711 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount()
2713 const glw::GLdouble double_values[16] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
2714 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
2715 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2717 const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV, UNIFORM_FUNCTION_2DV,
2718 UNIFORM_FUNCTION_3DV, UNIFORM_FUNCTION_4DV,
2719 UNIFORM_FUNCTION_MATRIX2DV, UNIFORM_FUNCTION_MATRIX2X3DV,
2720 UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
2721 UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
2722 UNIFORM_FUNCTION_MATRIX4DV, UNIFORM_FUNCTION_MATRIX4X2DV,
2723 UNIFORM_FUNCTION_MATRIX4X3DV };
2724 const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);
2726 for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
2728 _uniform_function uniform_function = uniform_functions[n_uniform_function];
2730 switch (uniform_function)
2732 case UNIFORM_FUNCTION_1DV:
2733 gl.uniform1dv(m_po_double_arr_uniform_location, -1, double_values);
2735 case UNIFORM_FUNCTION_2DV:
2736 gl.uniform2dv(m_po_dvec2_arr_uniform_location, -1, double_values);
2738 case UNIFORM_FUNCTION_3DV:
2739 gl.uniform3dv(m_po_dvec3_arr_uniform_location, -1, double_values);
2741 case UNIFORM_FUNCTION_4DV:
2742 gl.uniform4dv(m_po_dvec4_arr_uniform_location, -1, double_values);
2744 case UNIFORM_FUNCTION_MATRIX2DV:
2745 gl.uniformMatrix2dv(m_po_dmat2_arr_uniform_location, -1, GL_FALSE, double_values);
2747 case UNIFORM_FUNCTION_MATRIX2X3DV:
2748 gl.uniformMatrix2x3dv(m_po_dmat2x3_arr_uniform_location, -1, GL_FALSE, double_values);
2750 case UNIFORM_FUNCTION_MATRIX2X4DV:
2751 gl.uniformMatrix2x4dv(m_po_dmat2x4_arr_uniform_location, -1, GL_FALSE, double_values);
2753 case UNIFORM_FUNCTION_MATRIX3DV:
2754 gl.uniformMatrix3dv(m_po_dmat3_arr_uniform_location, -1, GL_FALSE, double_values);
2756 case UNIFORM_FUNCTION_MATRIX3X2DV:
2757 gl.uniformMatrix3x2dv(m_po_dmat3x2_arr_uniform_location, -1, GL_FALSE, double_values);
2759 case UNIFORM_FUNCTION_MATRIX3X4DV:
2760 gl.uniformMatrix3x4dv(m_po_dmat3x4_arr_uniform_location, -1, GL_FALSE, double_values);
2762 case UNIFORM_FUNCTION_MATRIX4DV:
2763 gl.uniformMatrix4dv(m_po_dmat4_arr_uniform_location, -1, GL_FALSE, double_values);
2765 case UNIFORM_FUNCTION_MATRIX4X2DV:
2766 gl.uniformMatrix4x2dv(m_po_dmat4x2_arr_uniform_location, -1, GL_FALSE, double_values);
2768 case UNIFORM_FUNCTION_MATRIX4X3DV:
2769 gl.uniformMatrix4x3dv(m_po_dmat4x3_arr_uniform_location, -1, GL_FALSE, double_values);
2774 TCU_FAIL("Unrecognized uniform function");
2776 } /* switch (uniform_function) */
2778 /* Make sure GL_INVALID_VALUE was generated */
2779 glw::GLenum error_code = gl.getError();
2781 if (error_code != GL_INVALID_VALUE)
2783 m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
2785 "was called with a negative count argument but did not generate a "
2786 "GL_INVALID_VALUE error"
2787 << tcu::TestLog::EndMessage;
2791 } /* for (all uniform functions) */
2796 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
2797 * glUniformMatrix*dv() functions is used to load an uniform that's incompatible with the
2798 * function (as per spec).
2800 * @return true if the implementation was found to behave as expected, false otherwise.
2802 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions()
2804 const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
2805 glw::GLenum error_code = GL_NO_ERROR;
2806 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2809 const glw::GLint double_uniform_locations[] = { m_po_dmat2_uniform_location, m_po_dmat2x3_uniform_location,
2810 m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location,
2811 m_po_dmat3x2_uniform_location, m_po_dmat3x4_uniform_location,
2812 m_po_dmat4_uniform_location, m_po_dmat4x2_uniform_location,
2813 m_po_dmat4x3_uniform_location, m_po_double_uniform_location,
2814 m_po_dvec2_uniform_location, m_po_dvec3_uniform_location,
2815 m_po_dvec4_uniform_location };
2816 const unsigned int n_double_uniform_locations =
2817 sizeof(double_uniform_locations) / sizeof(double_uniform_locations[0]);
2819 gl.useProgram(m_po_id);
2820 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2822 for (unsigned int n_uniform_location = 0; n_uniform_location < n_double_uniform_locations; ++n_uniform_location)
2824 glw::GLint uniform_location = double_uniform_locations[n_uniform_location];
2826 for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
2827 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); function++)
2829 _uniform_function e_function = static_cast<_uniform_function>(function);
2830 /* Exclude valid combinations */
2831 if (((uniform_location == m_po_dmat2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2DV)) ||
2832 ((uniform_location == m_po_dmat2x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X3DV)) ||
2833 ((uniform_location == m_po_dmat2x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X4DV)) ||
2834 ((uniform_location == m_po_dmat3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3DV)) ||
2835 ((uniform_location == m_po_dmat3x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X2DV)) ||
2836 ((uniform_location == m_po_dmat3x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X4DV)) ||
2837 ((uniform_location == m_po_dmat4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4DV)) ||
2838 ((uniform_location == m_po_dmat4x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X2DV)) ||
2839 ((uniform_location == m_po_dmat4x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X3DV)) ||
2840 ((uniform_location == m_po_double_uniform_location) &&
2841 ((e_function == UNIFORM_FUNCTION_1D) || (e_function == UNIFORM_FUNCTION_1DV))) ||
2842 ((uniform_location == m_po_dvec2_uniform_location) &&
2843 ((e_function == UNIFORM_FUNCTION_2D) || (e_function == UNIFORM_FUNCTION_2DV))) ||
2844 ((uniform_location == m_po_dvec3_uniform_location) &&
2845 ((e_function == UNIFORM_FUNCTION_3D) || (e_function == UNIFORM_FUNCTION_3DV))) ||
2846 ((uniform_location == m_po_dvec4_uniform_location) &&
2847 ((e_function == UNIFORM_FUNCTION_4D) || (e_function == UNIFORM_FUNCTION_4DV))))
2854 case UNIFORM_FUNCTION_1D:
2856 gl.uniform1d(uniform_location, double_data[0]);
2861 case UNIFORM_FUNCTION_2D:
2863 gl.uniform2d(uniform_location, double_data[0], double_data[1]);
2868 case UNIFORM_FUNCTION_3D:
2870 gl.uniform3d(uniform_location, double_data[0], double_data[1], double_data[2]);
2875 case UNIFORM_FUNCTION_4D:
2877 gl.uniform4d(uniform_location, double_data[0], double_data[1], double_data[2], double_data[3]);
2882 case UNIFORM_FUNCTION_1DV:
2883 gl.uniform1dv(uniform_location, 1 /* count */, double_data);
2885 case UNIFORM_FUNCTION_2DV:
2886 gl.uniform2dv(uniform_location, 1 /* count */, double_data);
2888 case UNIFORM_FUNCTION_3DV:
2889 gl.uniform3dv(uniform_location, 1 /* count */, double_data);
2891 case UNIFORM_FUNCTION_4DV:
2892 gl.uniform4dv(uniform_location, 1 /* count */, double_data);
2894 case UNIFORM_FUNCTION_MATRIX2DV:
2895 gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2897 case UNIFORM_FUNCTION_MATRIX2X3DV:
2898 gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2900 case UNIFORM_FUNCTION_MATRIX2X4DV:
2901 gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2903 case UNIFORM_FUNCTION_MATRIX3DV:
2904 gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2906 case UNIFORM_FUNCTION_MATRIX3X2DV:
2907 gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2909 case UNIFORM_FUNCTION_MATRIX3X4DV:
2910 gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2912 case UNIFORM_FUNCTION_MATRIX4DV:
2913 gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2915 case UNIFORM_FUNCTION_MATRIX4X2DV:
2916 gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2918 case UNIFORM_FUNCTION_MATRIX4X3DV:
2919 gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
2924 TCU_FAIL("Unrecognized function");
2926 } /* switch (function) */
2928 /* Make sure GL_INVALID_OPERATION error was generated */
2929 error_code = gl.getError();
2931 if (error_code != GL_INVALID_OPERATION)
2933 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error [" << error_code
2934 << "] was generated when a mismatched "
2935 "double-precision uniform function "
2936 << getUniformFunctionString(e_function) << "() was used to configure uniform "
2937 << getUniformNameForLocation(uniform_location) << "." << tcu::TestLog::EndMessage;
2941 } /* for (all uniform functions) */
2942 } /* for (all uniform locations) */
2947 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
2948 * glUniform*dv() functions is used to load an uniform, size of which is incompatible
2949 * with the function.
2951 * @return true if the implementation was found to behave as expected, false otherwise.
2953 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions()
2955 const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
2956 glw::GLenum error_code = GL_NO_ERROR;
2957 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2960 const int data[] = {
2961 /* API function */ /* Uniform location */ /* Count (dv functions only) */
2962 (int)UNIFORM_FUNCTION_2D, m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_2DV,
2963 m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_double_uniform_location, 0,
2964 (int)UNIFORM_FUNCTION_3DV, m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
2965 m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_double_uniform_location, 2,
2966 (int)UNIFORM_FUNCTION_1D, m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
2967 m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_dvec2_uniform_location, 0,
2968 (int)UNIFORM_FUNCTION_3DV, m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
2969 m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec2_uniform_location, 2,
2970 (int)UNIFORM_FUNCTION_1D, m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
2971 m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec3_uniform_location, 0,
2972 (int)UNIFORM_FUNCTION_2DV, m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
2973 m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec3_uniform_location, 2,
2974 (int)UNIFORM_FUNCTION_1D, m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
2975 m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec4_uniform_location, 0,
2976 (int)UNIFORM_FUNCTION_2DV, m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_3D,
2977 m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_3DV, m_po_dvec4_uniform_location, 2,
2979 const unsigned int n_checks = sizeof(data) / sizeof(data[0]) / 3 /* entries per row */;
2981 gl.useProgram(m_po_id);
2982 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2984 for (unsigned int n_check = 0; n_check < n_checks; ++n_check)
2986 _uniform_function function = (_uniform_function)data[n_check * 3 + 0];
2987 int uniform_location = data[n_check * 3 + 1];
2988 int uniform_count = data[n_check * 3 + 2];
2992 case UNIFORM_FUNCTION_1D:
2993 gl.uniform1d(uniform_location, 0.0);
2995 case UNIFORM_FUNCTION_1DV:
2996 gl.uniform1dv(uniform_location, uniform_count, double_data);
2998 case UNIFORM_FUNCTION_2D:
2999 gl.uniform2d(uniform_location, 0.0, 1.0);
3001 case UNIFORM_FUNCTION_2DV:
3002 gl.uniform2dv(uniform_location, uniform_count, double_data);
3004 case UNIFORM_FUNCTION_3D:
3005 gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
3007 case UNIFORM_FUNCTION_3DV:
3008 gl.uniform3dv(uniform_location, uniform_count, double_data);
3010 case UNIFORM_FUNCTION_4D:
3011 gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
3013 case UNIFORM_FUNCTION_4DV:
3014 gl.uniform4dv(uniform_location, uniform_count, double_data);
3021 } /* switch (function) */
3023 error_code = gl.getError();
3024 if (error_code != GL_INVALID_OPERATION)
3026 m_testCtx.getLog() << tcu::TestLog::Message << getUniformFunctionString(function)
3027 << "() function did not generate GL_INVALID_OPERATION error when called for"
3028 " a uniform of incompatible size. (check index: "
3029 << n_check << ")" << tcu::TestLog::EndMessage;
3033 } /* for (all checks) */
3038 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
3039 * glUniform*dv() functions is used to load an uniform, type of which is incompatible
3040 * with the function.
3042 * @return true if the implementation was found to behave as expected, false otherwise.
3044 bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions()
3046 const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
3047 glw::GLenum error_code = GL_NO_ERROR;
3048 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3051 const glw::GLint nondouble_uniform_locations[] = { m_po_bool_uniform_location, m_po_bvec2_uniform_location,
3052 m_po_bvec3_uniform_location, m_po_bvec4_uniform_location,
3053 m_po_float_uniform_location, m_po_int_uniform_location,
3054 m_po_ivec2_uniform_location, m_po_ivec3_uniform_location,
3055 m_po_ivec4_uniform_location, m_po_uint_uniform_location,
3056 m_po_uvec2_uniform_location, m_po_uvec3_uniform_location,
3057 m_po_uvec4_uniform_location, m_po_vec2_uniform_location,
3058 m_po_vec3_uniform_location, m_po_vec4_uniform_location };
3059 const unsigned int n_nondouble_uniform_locations =
3060 sizeof(nondouble_uniform_locations) / sizeof(nondouble_uniform_locations[0]);
3062 gl.useProgram(m_po_id);
3063 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
3065 for (unsigned int n_uniform_location = 0; n_uniform_location < n_nondouble_uniform_locations; ++n_uniform_location)
3067 glw::GLint uniform_location = nondouble_uniform_locations[n_uniform_location];
3069 for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
3070 function < static_cast<int>(UNIFORM_FUNCTION_COUNT); ++function)
3072 switch (static_cast<_uniform_function>(function))
3074 case UNIFORM_FUNCTION_1D:
3075 gl.uniform1d(uniform_location, 0.0);
3077 case UNIFORM_FUNCTION_1DV:
3078 gl.uniform1dv(uniform_location, 1, double_data);
3080 case UNIFORM_FUNCTION_2D:
3081 gl.uniform2d(uniform_location, 0.0, 1.0);
3083 case UNIFORM_FUNCTION_2DV:
3084 gl.uniform2dv(uniform_location, 1, double_data);
3086 case UNIFORM_FUNCTION_3D:
3087 gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
3089 case UNIFORM_FUNCTION_3DV:
3090 gl.uniform3dv(uniform_location, 1, double_data);
3092 case UNIFORM_FUNCTION_4D:
3093 gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
3095 case UNIFORM_FUNCTION_4DV:
3096 gl.uniform4dv(uniform_location, 1, double_data);
3099 case UNIFORM_FUNCTION_MATRIX2DV:
3100 gl.uniformMatrix2dv(uniform_location, 1, GL_FALSE, double_data);
3102 case UNIFORM_FUNCTION_MATRIX2X3DV:
3103 gl.uniformMatrix2x3dv(uniform_location, 1, GL_FALSE, double_data);
3105 case UNIFORM_FUNCTION_MATRIX2X4DV:
3106 gl.uniformMatrix2x4dv(uniform_location, 1, GL_FALSE, double_data);
3108 case UNIFORM_FUNCTION_MATRIX3DV:
3109 gl.uniformMatrix3dv(uniform_location, 1, GL_FALSE, double_data);
3111 case UNIFORM_FUNCTION_MATRIX3X2DV:
3112 gl.uniformMatrix3x2dv(uniform_location, 1, GL_FALSE, double_data);
3114 case UNIFORM_FUNCTION_MATRIX3X4DV:
3115 gl.uniformMatrix3x4dv(uniform_location, 1, GL_FALSE, double_data);
3117 case UNIFORM_FUNCTION_MATRIX4DV:
3118 gl.uniformMatrix4dv(uniform_location, 1, GL_FALSE, double_data);
3120 case UNIFORM_FUNCTION_MATRIX4X2DV:
3121 gl.uniformMatrix4x2dv(uniform_location, 1, GL_FALSE, double_data);
3123 case UNIFORM_FUNCTION_MATRIX4X3DV:
3124 gl.uniformMatrix4x3dv(uniform_location, 1, GL_FALSE, double_data);
3131 } /* switch (function) */
3133 error_code = gl.getError();
3134 if (error_code != GL_INVALID_OPERATION)
3136 m_testCtx.getLog() << tcu::TestLog::Message
3137 << getUniformFunctionString(static_cast<_uniform_function>(function))
3138 << "() function did not generate GL_INVALID_OPERATION error when called for"
3139 " a uniform of incompatible type."
3140 << tcu::TestLog::EndMessage;
3145 } /* for (all checks) */
3150 /** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
3151 * glUniform*dv() functions are called without a bound program object.
3153 * @return true if the implementation was found to behave as expected, false otherwise.
3155 bool GPUShaderFP64Test1::verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO()
3157 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3160 for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST); function < static_cast<int>(UNIFORM_FUNCTION_COUNT);
3163 const double data[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 };
3165 switch (static_cast<_uniform_function>(function))
3167 case UNIFORM_FUNCTION_1D:
3168 gl.uniform1d(m_po_double_uniform_location, 0.0);
3170 case UNIFORM_FUNCTION_1DV:
3171 gl.uniform1dv(m_po_double_uniform_location, 1, data);
3173 case UNIFORM_FUNCTION_2D:
3174 gl.uniform2d(m_po_dvec2_uniform_location, 0.0, 1.0);
3176 case UNIFORM_FUNCTION_2DV:
3177 gl.uniform2dv(m_po_dvec2_uniform_location, 1, data);
3179 case UNIFORM_FUNCTION_3D:
3180 gl.uniform3d(m_po_dvec3_uniform_location, 0.0, 1.0, 2.0);
3182 case UNIFORM_FUNCTION_3DV:
3183 gl.uniform3dv(m_po_dvec3_uniform_location, 1, data);
3185 case UNIFORM_FUNCTION_4D:
3186 gl.uniform4d(m_po_dvec4_uniform_location, 0.0, 1.0, 2.0, 3.0);
3188 case UNIFORM_FUNCTION_4DV:
3189 gl.uniform4dv(m_po_dvec4_uniform_location, 1, data);
3192 case UNIFORM_FUNCTION_MATRIX2DV:
3193 gl.uniformMatrix2dv(m_po_dmat2_uniform_location, 1, GL_FALSE /* transpose */, data);
3195 case UNIFORM_FUNCTION_MATRIX2X3DV:
3196 gl.uniformMatrix2x3dv(m_po_dmat2x3_uniform_location, 1, GL_FALSE /* transpose */, data);
3198 case UNIFORM_FUNCTION_MATRIX2X4DV:
3199 gl.uniformMatrix2x4dv(m_po_dmat2x4_uniform_location, 1, GL_FALSE /* transpose */, data);
3201 case UNIFORM_FUNCTION_MATRIX3DV:
3202 gl.uniformMatrix3dv(m_po_dmat3_uniform_location, 1, GL_FALSE /* transpose */, data);
3204 case UNIFORM_FUNCTION_MATRIX3X2DV:
3205 gl.uniformMatrix3x2dv(m_po_dmat3x2_uniform_location, 1, GL_FALSE /* transpose */, data);
3207 case UNIFORM_FUNCTION_MATRIX3X4DV:
3208 gl.uniformMatrix3x4dv(m_po_dmat3x4_uniform_location, 1, GL_FALSE /* transpose */, data);
3210 case UNIFORM_FUNCTION_MATRIX4DV:
3211 gl.uniformMatrix4dv(m_po_dmat4_uniform_location, 1, GL_FALSE /* transpose */, data);
3213 case UNIFORM_FUNCTION_MATRIX4X2DV:
3214 gl.uniformMatrix4x2dv(m_po_dmat4x2_uniform_location, 1, GL_FALSE /* transpose */, data);
3216 case UNIFORM_FUNCTION_MATRIX4X3DV:
3217 gl.uniformMatrix4x3dv(m_po_dmat4x3_uniform_location, 1, GL_FALSE /* transpose */, data);
3222 TCU_FAIL("Unrecognized uniform function");
3224 } /* switch (func) */
3226 /* Query the error code */
3227 glw::GLenum error_code = gl.getError();
3229 if (error_code != GL_INVALID_OPERATION)
3231 m_testCtx.getLog() << tcu::TestLog::Message << "Implementation did not return GL_INVALID_OPERATION when "
3232 << getUniformFunctionString(static_cast<_uniform_function>(function))
3233 << "() was called without an active program object" << tcu::TestLog::EndMessage;
3237 } /* for (all uniform functions) */
3242 /* Defeinitions of static const symbols declared in GPUShaderFP64Test2 */
3243 const glw::GLuint GPUShaderFP64Test2::m_n_captured_results = 1024;
3244 const glw::GLint GPUShaderFP64Test2::m_result_failure = 2;
3245 const glw::GLint GPUShaderFP64Test2::m_result_success = 1;
3246 const glw::GLuint GPUShaderFP64Test2::m_texture_width = 32;
3247 const glw::GLuint GPUShaderFP64Test2::m_texture_height = m_n_captured_results / m_texture_width;
3248 const glw::GLuint GPUShaderFP64Test2::m_transform_feedback_buffer_size =
3249 m_n_captured_results * sizeof(captured_varying_type);
3250 const glw::GLchar* GPUShaderFP64Test2::m_uniform_block_name = "UniformBlock";
3251 const glw::GLenum GPUShaderFP64Test2::ARB_MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263;
3255 * @param context Test context
3257 GPUShaderFP64Test2::GPUShaderFP64Test2(deqp::Context& context)
3258 : TestCase(context, "max_uniform_components",
3259 "Verifies that maximum allowed uniform components can be used as double-precision float types")
3260 , m_pDispatchCompute(0)
3261 , m_framebuffer_id(0)
3263 , m_transform_feedback_buffer_id(0)
3264 , m_uniform_buffer_id(0)
3265 , m_vertex_array_object_id(0)
3267 /* Nothing to be done */
3270 /** Deinitialize test
3273 void GPUShaderFP64Test2::deinit()
3275 /* GL entry points */
3276 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3278 /* Clean frambuffer */
3279 if (0 != m_framebuffer_id)
3281 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3282 gl.deleteFramebuffers(1, &m_framebuffer_id);
3283 m_framebuffer_id = 0;
3287 if (0 != m_texture_id)
3289 gl.bindTexture(GL_TEXTURE_2D, 0);
3290 gl.bindImageTexture(0 /* unit */, 0 /* texture */, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
3291 GL_READ_ONLY, GL_RGBA8);
3292 gl.deleteTextures(1, &m_texture_id);
3297 if (0 != m_transform_feedback_buffer_id)
3299 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
3300 gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
3301 m_transform_feedback_buffer_id = 0;
3304 if (0 != m_uniform_buffer_id)
3306 gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
3307 gl.deleteBuffers(1, &m_uniform_buffer_id);
3308 m_uniform_buffer_id = 0;
3312 if (0 != m_vertex_array_object_id)
3314 gl.bindVertexArray(0);
3315 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
3316 m_vertex_array_object_id = 0;
3322 * @return tcu::TestNode::STOP
3324 tcu::TestNode::IterateResult GPUShaderFP64Test2::iterate()
3328 /* Check if extension is supported */
3329 if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
3331 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
3334 /* Initialize test */
3337 prepareShaderStages();
3338 prepareUniformTypes();
3340 /* For all shaders and uniform type combinations */
3341 for (std::vector<shaderStage>::const_iterator shader_stage = m_shader_stages.begin();
3342 m_shader_stages.end() != shader_stage; ++shader_stage)
3344 for (std::vector<uniformTypeDetails>::const_iterator uniform_type = m_uniform_types.begin();
3345 m_uniform_types.end() != uniform_type; ++uniform_type)
3348 if (false == test(*shader_stage, *uniform_type))
3358 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
3362 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3366 return tcu::TestNode::STOP;
3371 * @param n_columns Number of columns
3372 * @param n_rows Number of rows
3374 GPUShaderFP64Test2::uniformTypeDetails::uniformTypeDetails(glw::GLuint n_columns, glw::GLuint n_rows)
3375 : m_n_columns(n_columns), m_n_rows(n_rows)
3377 Utils::_variable_type type = Utils::getDoubleVariableType(n_columns, n_rows);
3379 m_type_name = Utils::getVariableTypeString(type);
3380 m_type = Utils::getGLDataTypeOfVariableType(type);
3383 /** Get primitive type captured with transform feedback
3385 * @param shader_stage Tested shader stage id
3387 * @return Primitive type
3389 glw::GLenum GPUShaderFP64Test2::getCapturedPrimitiveType(shaderStage shader_stage) const
3391 switch (shader_stage)
3393 case GEOMETRY_SHADER:
3394 case TESS_CTRL_SHADER:
3395 case TESS_EVAL_SHADER:
3406 /** Get primitive type drawn with DrawArrays
3408 * @param shader_stage Tested shader stage id
3410 * @return Primitive type
3412 glw::GLenum GPUShaderFP64Test2::getDrawPrimitiveType(shaderStage shader_stage) const
3414 switch (shader_stage)
3416 case FRAGMENT_SHADER:
3417 return GL_TRIANGLE_FAN;
3420 case GEOMETRY_SHADER:
3425 case TESS_CTRL_SHADER:
3426 case TESS_EVAL_SHADER:
3436 /** Get maximum allowed number of uniform components
3438 * @param shader_stage Tested shader stage id
3440 * @return Maxmimum uniform components
3442 glw::GLuint GPUShaderFP64Test2::getMaxUniformComponents(shaderStage shader_stage) const
3444 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3445 glw::GLint max_uniform_components = 0;
3446 glw::GLenum pname = 0;
3448 switch (shader_stage)
3450 case COMPUTE_SHADER:
3451 pname = ARB_MAX_COMPUTE_UNIFORM_COMPONENTS;
3453 case FRAGMENT_SHADER:
3454 pname = GL_MAX_FRAGMENT_UNIFORM_COMPONENTS;
3456 case GEOMETRY_SHADER:
3457 pname = GL_MAX_GEOMETRY_UNIFORM_COMPONENTS;
3459 case TESS_CTRL_SHADER:
3460 pname = GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS;
3462 case TESS_EVAL_SHADER:
3463 pname = GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS;
3466 pname = GL_MAX_VERTEX_UNIFORM_COMPONENTS;
3470 gl.getIntegerv(pname, &max_uniform_components);
3471 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3473 return max_uniform_components;
3476 /** Get maximum size allowed for an uniform block
3478 * @return Maxmimum uniform block size
3480 glw::GLuint GPUShaderFP64Test2::getMaxUniformBlockSize() const
3482 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3483 glw::GLint max_uniform_block_size = 0;
3485 gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_block_size);
3486 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3488 return max_uniform_block_size;
3491 /** Get number of components required to store single uniform of given type
3493 * @param uniform_type Tested uniform type
3495 * @return Number of components
3497 glw::GLuint GPUShaderFP64Test2::getRequiredComponentsNumber(const uniformTypeDetails& uniform_type) const
3499 static const glw::GLuint type_size = 2; /* double takes 2 N */
3500 const glw::GLuint column_length = uniform_type.m_n_rows;
3502 if (1 == uniform_type.m_n_columns)
3504 return type_size * column_length;
3508 const glw::GLuint alignment = type_size * ((3 == column_length) ? 4 : column_length);
3510 return alignment * uniform_type.m_n_columns;
3514 /** Get size used for each member of a uniform array of a given type in a std140 column-major layout
3516 * @param uniform_type Tested uniform type
3518 * @return Size of a single member
3520 glw::GLuint GPUShaderFP64Test2::getUniformTypeMemberSize(const uniformTypeDetails& uniform_type) const
3522 static const glw::GLuint vec4_size = 4 * Utils::getBaseVariableTypeComponentSize(Utils::VARIABLE_TYPE_FLOAT);
3523 const glw::GLuint column_length = uniform_type.m_n_rows;
3525 /** Size for a layout(std140, column_major) uniform_type uniform[] **/
3526 return vec4_size * ((column_length + 1) / 2) * uniform_type.m_n_columns;
3529 /** Get the maximum amount of uniforms to be used in a shader stage for a given type
3531 * @param shader_stage Tested shader stage id
3532 * @param uniform_type Tested uniform type
3534 * @return Number of components
3536 glw::GLuint GPUShaderFP64Test2::getAmountUniforms(shaderStage shader_stage,
3537 const uniformTypeDetails& uniform_type) const
3539 const glw::GLuint max_uniform_components = getMaxUniformComponents(shader_stage);
3540 const glw::GLuint required_components = getRequiredComponentsNumber(uniform_type);
3541 const glw::GLuint n_uniforms = max_uniform_components / required_components;
3542 const glw::GLuint max_uniform_block_size = getMaxUniformBlockSize();
3543 const glw::GLuint uniform_type_member_size = getUniformTypeMemberSize(uniform_type);
3544 const glw::GLuint max_uniforms = max_uniform_block_size / uniform_type_member_size;
3546 return max_uniforms < n_uniforms ? max_uniforms : n_uniforms;
3549 /** Get name of shader stage
3551 * @param shader_stage Tested shader stage id
3555 const glw::GLchar* GPUShaderFP64Test2::getShaderStageName(shaderStage shader_stage) const
3557 switch (shader_stage)
3559 case COMPUTE_SHADER:
3560 return "compute shader";
3562 case FRAGMENT_SHADER:
3563 return "fragment shader";
3565 case GEOMETRY_SHADER:
3566 return "geometry shader";
3568 case TESS_CTRL_SHADER:
3569 return "tesselation control shader";
3571 case TESS_EVAL_SHADER:
3572 return "tesselation evaluation shader";
3575 return "vertex shader";
3582 /** Inspect program to get: buffer_size, offset, strides and block index
3584 * @param program_id Program id
3585 * @param out_buffer_size Size of uniform buffer
3586 * @param out_uniform_details Uniform offset and strides
3587 * @param uniform_block_index Uniform block index
3589 void GPUShaderFP64Test2::inspectProgram(glw::GLuint program_id, glw::GLint n_uniforms,
3590 const uniformTypeDetails& uniform_type, glw::GLint& out_buffer_size,
3591 uniformDetails& out_uniform_details, glw::GLuint uniform_block_index) const
3593 glw::GLint array_stride = 0;
3594 std::vector<glw::GLchar> extracted_uniform_name;
3595 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3596 glw::GLuint index = 0;
3597 glw::GLint matrix_stride = 0;
3598 glw::GLint offset = 0;
3599 glw::GLsizei size = 0;
3600 glw::GLenum type = 0;
3601 const glw::GLchar* uniform_name = 0;
3602 std::string uniform_name_str;
3603 std::stringstream uniform_name_stream;
3605 /* Get index of uniform block */
3606 uniform_block_index = gl.getUniformBlockIndex(program_id, m_uniform_block_name);
3607 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex");
3609 if (GL_INVALID_INDEX == uniform_block_index)
3611 TCU_FAIL("Unifom block is inactive");
3614 /* Get size of uniform block */
3615 gl.getActiveUniformBlockiv(program_id, uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &out_buffer_size);
3616 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv");
3618 if (0 == out_buffer_size)
3620 TCU_FAIL("Unifom block size is 0");
3623 /* Prepare uniform name */
3624 uniform_name_stream << "uniform_array";
3626 uniform_name_str = uniform_name_stream.str();
3627 uniform_name = uniform_name_str.c_str();
3629 /* Get index of uniform */
3630 gl.getUniformIndices(program_id, 1 /* count */, &uniform_name, &index);
3631 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
3633 if (GL_INVALID_INDEX == index)
3635 TCU_FAIL("Unifom is inactive");
3638 /* Verify getActiveUniform results */
3639 extracted_uniform_name.resize(uniform_name_str.length() * 2);
3641 gl.getActiveUniform(program_id, index, (glw::GLsizei)(uniform_name_str.length() * 2) /* bufSize */, 0, &size, &type,
3642 &extracted_uniform_name[0]);
3643 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniform");
3645 if ((n_uniforms != size) || (uniform_type.m_type != type))
3647 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid GetActiveUniform results."
3648 << " Size: " << size << " expected: " << n_uniforms << ". Type: " << type
3649 << " expected: " << uniform_type.m_type
3650 << ". Name: " << &extracted_uniform_name[0] << tcu::TestLog::EndMessage;
3652 TCU_FAIL("Invalid GetActiveUniform results");
3655 /* Get offset of uniform */
3656 gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset);
3657 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
3661 TCU_FAIL("Unifom has invalid offset");
3664 out_uniform_details.m_offset = offset;
3666 /* Get matrix stride of uniform */
3667 gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
3668 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
3670 if (-1 == matrix_stride)
3672 TCU_FAIL("Unifom has invalid matrix stride");
3675 out_uniform_details.m_matrix_stride = matrix_stride;
3677 /* Get array stride of uniform */
3678 gl.getActiveUniformsiv(program_id, 1 /* count */, &index, GL_UNIFORM_ARRAY_STRIDE, &array_stride);
3679 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
3681 if (-1 == matrix_stride)
3683 TCU_FAIL("Unifom has invalid matrix stride");
3686 out_uniform_details.m_array_stride = array_stride;
3689 /** Prepare source code for "boilerplate" shaders
3691 * @param stage_specific_layout String that will replace STAGE_SPECIFIC_LAYOUT token
3692 * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token
3693 * @param out_source_code Source code
3695 void GPUShaderFP64Test2::prepareBoilerplateShader(const glw::GLchar* stage_specific_layout,
3696 const glw::GLchar* stage_specific_main_body,
3697 std::string& out_source_code) const
3699 /* Shader template */
3700 static const glw::GLchar* boilerplate_shader_template_code = "#version 400 core\n"
3702 "precision highp float;\n"
3704 "STAGE_SPECIFIC_LAYOUT"
3707 "STAGE_SPECIFIC_MAIN_BODY"
3711 std::string string = boilerplate_shader_template_code;
3714 static const glw::GLchar* body_token = "STAGE_SPECIFIC_MAIN_BODY";
3715 static const glw::GLchar* layout_token = "STAGE_SPECIFIC_LAYOUT";
3717 size_t search_position = 0;
3719 /* Replace tokens */
3720 Utils::replaceToken(layout_token, search_position, stage_specific_layout, string);
3721 Utils::replaceToken(body_token, search_position, stage_specific_main_body, string);
3724 out_source_code = string;
3727 /** Prepare program for given combination of shader stage and uniform type
3729 * @param shader_stage Shader stage
3730 * @param uniform_type Uniform type
3731 * @param out_program_info Instance of programInfo
3733 void GPUShaderFP64Test2::prepareProgram(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
3734 Utils::programInfo& out_program_info) const
3736 /* Stage specific layouts */
3737 static const glw::GLchar* geometry_shader_layout_code = "layout(points) in;\n"
3738 "layout(points, max_vertices = 1) out;\n"
3741 static const glw::GLchar* tess_ctrl_shader_layout_code = "layout(vertices = 1) out;\n"
3744 static const glw::GLchar* tess_eval_shader_layout_code = "layout(isolines, point_mode) in;\n"
3747 /* Stage specific main body */
3748 static const glw::GLchar* boilerplate_fragment_shader_body_code = " discard;\n";
3750 static const glw::GLchar* boilerplate_tess_ctrl_shader_body_code = " gl_TessLevelOuter[0] = 1.0;\n"
3751 " gl_TessLevelOuter[1] = 1.0;\n"
3752 " gl_TessLevelOuter[2] = 1.0;\n"
3753 " gl_TessLevelOuter[3] = 1.0;\n"
3754 " gl_TessLevelInner[0] = 1.0;\n"
3755 " gl_TessLevelInner[1] = 1.0;\n";
3757 static const glw::GLchar* boilerplate_vertex_shader_body_code = " gl_Position = vec4(1, 0, 0, 1);\n";
3759 static const glw::GLchar* corner_vertex_shader_body_code = " if (0 == gl_VertexID)\n"
3761 " gl_Position = vec4(-1, -1, 0, 1);\n"
3763 " else if (1 == gl_VertexID)\n"
3765 " gl_Position = vec4(-1, 1, 0, 1);\n"
3767 " else if (2 == gl_VertexID)\n"
3769 " gl_Position = vec4(1, 1, 0, 1);\n"
3771 " else if (3 == gl_VertexID)\n"
3773 " gl_Position = vec4(1, -1, 0, 1);\n"
3776 static const glw::GLchar* passthrough_tess_eval_shader_body_code = " result = tcs_tes_result[0];\n";
3778 static const glw::GLchar* test_shader_body_code = "\n result = verification_result;\n";
3780 static const glw::GLchar* test_geometry_shader_body_code = "\n result = verification_result;\n"
3783 " EndPrimitive();\n";
3785 static const glw::GLchar* test_tess_ctrl_shader_body_code =
3786 "\n tcs_tes_result[gl_InvocationID] = verification_result;\n"
3788 " gl_TessLevelOuter[0] = 1.0;\n"
3789 " gl_TessLevelOuter[1] = 1.0;\n"
3790 " gl_TessLevelOuter[2] = 1.0;\n"
3791 " gl_TessLevelOuter[3] = 1.0;\n"
3792 " gl_TessLevelInner[0] = 1.0;\n"
3793 " gl_TessLevelInner[1] = 1.0;\n";
3796 static const glw::GLchar* test_tess_ctrl_shader_in_variable = "in int tcs_tes_result[];\n";
3799 static const glw::GLchar* test_fragment_shader_out_variable = "layout(location = 0) out int result;\n";
3801 static const glw::GLchar* test_tess_ctrl_shader_out_variable = "out int tcs_tes_result[];\n";
3803 static const glw::GLchar* test_shader_out_variable = "out int result;\n";
3806 static const glw::GLchar* varying_name = "result";
3807 glw::GLuint n_varyings = 1;
3809 /* Storage for ready shaders */
3810 std::string compute_shader_code;
3811 std::string fragment_shader_code;
3812 std::string geometry_shader_code;
3813 std::string tess_ctrl_shader_code;
3814 std::string tess_eval_shader_code;
3815 std::string vertex_shader_code;
3817 /* Storage for uniform definition and verification code */
3818 std::string uniform_definitions;
3819 std::string uniform_verification;
3821 /* Get uniform definition and verification code */
3822 prepareUniformDefinitions(shader_stage, uniform_type, uniform_definitions);
3823 prepareUniformVerification(shader_stage, uniform_type, uniform_verification);
3825 /* Prepare vertex shader */
3826 switch (shader_stage)
3828 case FRAGMENT_SHADER:
3830 prepareBoilerplateShader("", corner_vertex_shader_body_code, vertex_shader_code);
3834 case GEOMETRY_SHADER:
3835 case TESS_CTRL_SHADER:
3836 case TESS_EVAL_SHADER:
3838 prepareBoilerplateShader("", boilerplate_vertex_shader_body_code, vertex_shader_code);
3844 prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */,
3845 test_shader_out_variable /* out var */, uniform_verification.c_str() /* verification */,
3846 test_shader_body_code /* body */, vertex_shader_code);
3854 /* Prepare fragment shader */
3855 switch (shader_stage)
3857 case FRAGMENT_SHADER:
3859 prepareTestShader("" /* layout */, uniform_definitions.c_str() /* uniforms */, "" /* in var */,
3860 test_fragment_shader_out_variable /* out var */,
3861 uniform_verification.c_str() /* verification */, test_shader_body_code /* body */,
3862 fragment_shader_code);
3866 case GEOMETRY_SHADER:
3867 case TESS_CTRL_SHADER:
3868 case TESS_EVAL_SHADER:
3871 prepareBoilerplateShader("" /* layout */, boilerplate_fragment_shader_body_code /* body */,
3872 fragment_shader_code);
3880 /* Prepare compute, tess_ctrl, tess_eval, geometry shaders */
3881 switch (shader_stage)
3883 case COMPUTE_SHADER:
3885 prepareTestComputeShader(uniform_definitions.c_str(), uniform_verification.c_str(), compute_shader_code);
3889 case GEOMETRY_SHADER:
3891 prepareTestShader(geometry_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
3892 "" /* in var */, test_shader_out_variable /* out var */,
3893 uniform_verification.c_str() /* verification */, test_geometry_shader_body_code /* body */,
3894 geometry_shader_code);
3898 case TESS_CTRL_SHADER:
3900 prepareTestShader(tess_ctrl_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
3901 "" /* in var */, test_tess_ctrl_shader_out_variable /* out var */,
3902 uniform_verification.c_str() /* verification */, test_tess_ctrl_shader_body_code /* body */,
3903 tess_ctrl_shader_code);
3905 prepareTestShader(tess_eval_shader_layout_code /* layout */, "" /* uniforms */,
3906 test_tess_ctrl_shader_in_variable /* in var */, test_shader_out_variable /* out var */,
3907 "" /* verification */, passthrough_tess_eval_shader_body_code /* body */,
3908 tess_eval_shader_code);
3912 case TESS_EVAL_SHADER:
3914 prepareBoilerplateShader(tess_ctrl_shader_layout_code /* layout */,
3915 boilerplate_tess_ctrl_shader_body_code /* body */, tess_ctrl_shader_code);
3917 prepareTestShader(tess_eval_shader_layout_code /* layout */, uniform_definitions.c_str() /* uniforms */,
3918 "" /* in var */, test_shader_out_variable /* out var */,
3919 uniform_verification.c_str() /* verification */, test_shader_body_code /* body */,
3920 tess_eval_shader_code);
3928 /* Select shaders that will be used by program */
3929 const glw::GLchar* cs_c_str = 0;
3930 const glw::GLchar* fs_c_str = 0;
3931 const glw::GLchar* gs_c_str = 0;
3932 const glw::GLchar* tcs_c_str = 0;
3933 const glw::GLchar* tes_c_str = 0;
3934 const glw::GLchar* vs_c_str = 0;
3936 if (false == compute_shader_code.empty())
3938 cs_c_str = compute_shader_code.c_str();
3941 if (false == fragment_shader_code.empty())
3943 fs_c_str = fragment_shader_code.c_str();
3946 if (false == geometry_shader_code.empty())
3948 gs_c_str = geometry_shader_code.c_str();
3951 if (false == tess_ctrl_shader_code.empty())
3953 tcs_c_str = tess_ctrl_shader_code.c_str();
3956 if (false == tess_eval_shader_code.empty())
3958 tes_c_str = tess_eval_shader_code.c_str();
3961 if (false == vertex_shader_code.empty())
3963 vs_c_str = vertex_shader_code.c_str();
3966 /* Compute and fragment shader results are stored in texture, do not set varyings for transfrom feedback */
3967 if ((COMPUTE_SHADER == shader_stage) || (FRAGMENT_SHADER == shader_stage))
3973 out_program_info.build(cs_c_str, fs_c_str, gs_c_str, tcs_c_str, tes_c_str, vs_c_str, &varying_name, n_varyings);
3976 /** Prepare collection of tested shader stages
3979 void GPUShaderFP64Test2::prepareShaderStages()
3981 /* m_pDispatchCompute is initialized only if compute_shader are supproted and context is at least 4.2 */
3982 if (0 != m_pDispatchCompute)
3984 m_shader_stages.push_back(COMPUTE_SHADER);
3987 m_shader_stages.push_back(FRAGMENT_SHADER);
3988 m_shader_stages.push_back(GEOMETRY_SHADER);
3989 m_shader_stages.push_back(TESS_CTRL_SHADER);
3990 m_shader_stages.push_back(TESS_EVAL_SHADER);
3991 m_shader_stages.push_back(VERTEX_SHADER);
3994 /** Prepare source code for "tested" shader stage
3996 * @param stage_specific_layout String that will replace STAGE_SPECIFIC_LAYOUT token
3997 * @param uniform_definitions String that will replace UNIFORM_DEFINITIONS token
3998 * @param in_variable_definitions String that will replace IN_VARIABLE_DEFINITION token
3999 * @param out_variable_definitions String that will replace OUT_VARIABLE_DEFINITION token
4000 * @param uniform_verification String that will replace UNIFORM_VERIFICATION token
4001 * @param stage_specific_main_body String that will replace STAGE_SPECIFIC_MAIN_BODY token
4002 * @param out_source_code Shader source code
4004 void GPUShaderFP64Test2::prepareTestShader(const glw::GLchar* stage_specific_layout,
4005 const glw::GLchar* uniform_definitions,
4006 const glw::GLchar* in_variable_definitions,
4007 const glw::GLchar* out_variable_definitions,
4008 const glw::GLchar* uniform_verification,
4009 const glw::GLchar* stage_specific_main_body,
4010 std::string& out_source_code) const
4012 /* Shader template */
4013 static const glw::GLchar* test_shader_template_code = "#version 400 core\n"
4015 "precision highp float;\n"
4017 "STAGE_SPECIFIC_LAYOUT"
4018 "UNIFORM_DEFINITIONS"
4019 "IN_VARIABLE_DEFINITION"
4020 "OUT_VARIABLE_DEFINITION"
4024 "UNIFORM_VERIFICATION"
4025 "STAGE_SPECIFIC_MAIN_BODY"
4029 std::string string = test_shader_template_code;
4032 static const glw::GLchar* body_token = "STAGE_SPECIFIC_MAIN_BODY";
4033 static const glw::GLchar* in_var_token = "IN_VARIABLE_DEFINITION";
4034 static const glw::GLchar* layout_token = "STAGE_SPECIFIC_LAYOUT";
4035 static const glw::GLchar* out_var_token = "OUT_VARIABLE_DEFINITION";
4036 static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS";
4037 static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION";
4039 size_t search_position = 0;
4041 /* Replace tokens */
4042 Utils::replaceToken(layout_token, search_position, stage_specific_layout, string);
4043 Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string);
4044 Utils::replaceToken(in_var_token, search_position, in_variable_definitions, string);
4045 Utils::replaceToken(out_var_token, search_position, out_variable_definitions, string);
4046 Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string);
4047 Utils::replaceToken(body_token, search_position, stage_specific_main_body, string);
4050 out_source_code = string;
4053 /** Prepare source code for "tested" compute shaders
4055 * @param uniform_definitions String that will replace UNIFORM_DEFINITIONS token
4056 * @param uniform_verification String that will replace UNIFORM_VERIFICATION token
4057 * @param out_source_code Source code
4059 void GPUShaderFP64Test2::prepareTestComputeShader(const glw::GLchar* uniform_definitions,
4060 const glw::GLchar* uniform_verification,
4061 std::string& out_source_code) const
4063 /* Shader template */
4064 static const glw::GLchar* test_shader_template_code =
4065 "#version 420 core\n"
4066 "#extension GL_ARB_compute_shader : require\n"
4067 "#extension GL_ARB_shader_image_load_store : require\n"
4069 "precision highp float;\n"
4071 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
4073 "UNIFORM_DEFINITIONS"
4074 "layout(r32i) writeonly uniform iimage2D result;\n"
4078 "UNIFORM_VERIFICATION"
4080 " imageStore(result, ivec2(gl_WorkGroupID.xy), ivec4(verification_result, 0, 0, 0));\n"
4084 std::string string = test_shader_template_code;
4087 static const glw::GLchar* uni_def_token = "UNIFORM_DEFINITIONS";
4088 static const glw::GLchar* uni_ver_token = "UNIFORM_VERIFICATION";
4090 size_t search_position = 0;
4092 /* Replace tokens */
4093 Utils::replaceToken(uni_def_token, search_position, uniform_definitions, string);
4094 Utils::replaceToken(uni_ver_token, search_position, uniform_verification, string);
4097 out_source_code = string;
4100 /** Prepare source code which defines uniforms for tested shader stage
4102 * @param shader_stage Shader stage id
4103 * @param uniform_type Details of uniform type
4104 * @param out_source_code Source code
4106 void GPUShaderFP64Test2::prepareUniformDefinitions(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
4107 std::string& out_source_code) const
4109 const glw::GLuint n_uniforms = getAmountUniforms(shader_stage, uniform_type);
4110 std::stringstream stream;
4113 * layout(std140) uniform M_UNIFORM_BLOCK_NAME
4115 * TYPE_NAME uniform_array[N_UNIFORMS];
4118 stream << "layout(std140) uniform " << m_uniform_block_name << "\n"
4121 stream << " " << uniform_type.m_type_name << " uniform_array[" << n_uniforms << "];\n";
4125 out_source_code = stream.str();
4128 /** Prepare uniform buffer for test
4130 * @param shader_stage Shader stage id
4131 * @param uniform_type Details of uniform type
4132 * @param program_info Program object info
4134 void GPUShaderFP64Test2::prepareUniforms(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
4135 const Utils::programInfo& program_info) const
4137 glw::GLint buffer_size = 0;
4138 glw::GLuint element_ordinal = 1;
4139 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4140 const glw::GLuint n_columns = uniform_type.m_n_columns;
4141 const glw::GLuint n_rows = uniform_type.m_n_rows;
4142 const glw::GLuint n_elements = n_columns * n_rows;
4143 uniformDetails uniform_details;
4144 const glw::GLuint program_id = program_info.m_program_object_id;
4145 const glw::GLint n_uniforms = getAmountUniforms(shader_stage, uniform_type);
4146 std::vector<glw::GLubyte> uniform_buffer_data;
4147 glw::GLuint uniform_block_index = 0;
4149 /* Get uniform details */
4150 inspectProgram(program_id, n_uniforms, uniform_type, buffer_size, uniform_details, uniform_block_index);
4152 /* Uniform offset and strides */
4153 const glw::GLuint array_stride = uniform_details.m_array_stride;
4154 const glw::GLuint matrix_stride = uniform_details.m_matrix_stride;
4155 const glw::GLuint uniform_offset = uniform_details.m_offset;
4157 /* Prepare storage for buffer data */
4158 uniform_buffer_data.resize(buffer_size);
4160 /* Prepare uniform data */
4161 for (glw::GLint i = 0; i < n_uniforms; ++i)
4163 const glw::GLuint array_entry_offset = uniform_offset + i * array_stride;
4165 for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal)
4167 const glw::GLuint column = element / n_rows;
4168 const glw::GLuint column_elem = element % n_rows;
4169 const glw::GLdouble value = element_ordinal;
4170 const glw::GLuint value_offset = static_cast<glw::GLuint>(array_entry_offset + column * matrix_stride +
4171 column_elem * sizeof(glw::GLdouble));
4172 glw::GLdouble* value_dst = (glw::GLdouble*)&uniform_buffer_data[value_offset];
4178 /* Update uniform buffer with new set of data */
4179 gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id);
4180 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
4182 gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &uniform_buffer_data[0], GL_STATIC_DRAW);
4183 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
4185 /* Bind uniform block to uniform buffer */
4186 gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0 /* offset */, buffer_size);
4187 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
4189 gl.uniformBlockBinding(program_id, uniform_block_index, 0 /* binding */);
4190 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding");
4193 /** Prepare collection of tested uniform types
4196 void GPUShaderFP64Test2::prepareUniformTypes()
4198 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 1 /* n_rows */));
4199 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 2 /* n_rows */));
4200 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 3 /* n_rows */));
4201 m_uniform_types.push_back(uniformTypeDetails(1 /* n_columns */, 4 /* n_rows */));
4202 m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 2 /* n_rows */));
4203 m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 3 /* n_rows */));
4204 m_uniform_types.push_back(uniformTypeDetails(2 /* n_columns */, 4 /* n_rows */));
4205 m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 2 /* n_rows */));
4206 m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 3 /* n_rows */));
4207 m_uniform_types.push_back(uniformTypeDetails(3 /* n_columns */, 4 /* n_rows */));
4208 m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 2 /* n_rows */));
4209 m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 3 /* n_rows */));
4210 m_uniform_types.push_back(uniformTypeDetails(4 /* n_columns */, 4 /* n_rows */));
4213 /** Prepare source code that verifes uniform values
4215 * @param shader_stage Shader stage id
4216 * @param uniform_type Details of uniform type
4217 * @param out_source_code Source code
4219 void GPUShaderFP64Test2::prepareUniformVerification(shaderStage shader_stage, const uniformTypeDetails& uniform_type,
4220 std::string& out_source_code) const
4222 glw::GLuint element_ordinal = 1;
4223 const glw::GLuint n_columns = uniform_type.m_n_columns;
4224 const glw::GLuint n_rows = uniform_type.m_n_rows;
4225 const glw::GLuint n_elements = n_columns * n_rows;
4226 const glw::GLuint n_uniforms = getAmountUniforms(shader_stage, uniform_type);
4227 std::stringstream stream;
4230 * int verification_result = M_RESULT_SUCCESS;
4232 * for (int i = 0; i < N_UNIFORMS; ++i)
4234 * if (TYPE_NAME(i * (N_ELEMENTS) + 1) != uniform_array[i])
4236 * verification_result = M_RESULT_FAILURE
4240 stream << " int verification_result = " << m_result_success << ";\n"
4242 " for (int i = 0; i < "
4243 << n_uniforms << "; ++i)\n"
4246 << uniform_type.m_type_name << "(";
4248 for (glw::GLuint element = 0; element < n_elements; ++element, ++element_ordinal)
4250 stream << "i * (" << n_elements << ") + " << element + 1;
4252 if (n_elements != element + 1)
4258 stream << ") != uniform_array[i])\n"
4260 " verification_result = "
4261 << m_result_failure << ";\n"
4265 out_source_code = stream.str();
4268 /** Execute test for given combination of "tested" shader stage and uniform type
4270 * @param shader_stage Tested shader stage id
4271 * @param uniform_type Tested uniform type
4273 * @return true if test passed, false otherwise
4275 bool GPUShaderFP64Test2::test(shaderStage shader_stage, const uniformTypeDetails& uniform_type) const
4277 const glw::GLenum draw_primitive = getDrawPrimitiveType(shader_stage);
4278 static const glw::GLint first_vertex = 0;
4279 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4280 const glw::GLsizei n_vertices = (FRAGMENT_SHADER == shader_stage) ? 4 : m_n_captured_results;
4281 Utils::programInfo program_info(m_context);
4284 /* Prepare program */
4285 prepareProgram(shader_stage, uniform_type, program_info);
4287 gl.useProgram(program_info.m_program_object_id);
4288 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
4290 /* Prepare uniform buffer and bind it with uniform block */
4291 prepareUniforms(shader_stage, uniform_type, program_info);
4293 /* Prepare storage for test results */
4294 testBegin(program_info.m_program_object_id, shader_stage);
4297 if (COMPUTE_SHADER == shader_stage)
4299 m_pDispatchCompute(m_texture_width, m_texture_height, 1);
4300 GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
4304 gl.drawArrays(draw_primitive, first_vertex, n_vertices);
4305 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
4308 /* Clean after test */
4309 testEnd(shader_stage);
4312 if (false == verifyResults(shader_stage))
4314 m_context.getTestContext().getLog()
4315 << tcu::TestLog::Message << "Shader stage: " << getShaderStageName(shader_stage)
4316 << ". Uniform type: " << uniform_type.m_type_name << tcu::TestLog::EndMessage;
4324 /** Prepare transform feedback buffer, framebuffer or image unit for test results
4326 * @param program_id Program object id
4327 * @param shader_stage Tested shader stage id
4329 void GPUShaderFP64Test2::testBegin(glw::GLuint program_id, shaderStage shader_stage) const
4331 std::vector<glw::GLint> buffer_data;
4332 const glw::GLenum captured_primitive = getCapturedPrimitiveType(shader_stage);
4333 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4335 /* Prepare buffer filled with m_result_failure */
4336 buffer_data.resize(m_n_captured_results);
4337 for (glw::GLuint i = 0; i < m_n_captured_results; ++i)
4339 buffer_data[i] = m_result_failure;
4342 /* Prepare buffer for test results */
4343 switch (shader_stage)
4345 case GEOMETRY_SHADER:
4346 case TESS_CTRL_SHADER:
4347 case TESS_EVAL_SHADER:
4350 /* Verify getTransformFeedbackVarying results */
4352 glw::GLsizei size = 0;
4353 glw::GLenum type = 0;
4354 glw::GLchar name[16];
4356 gl.getTransformFeedbackVarying(program_id, 0 /* index */, 16 /* bufSize */, 0 /* length */, &size, &type,
4358 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTransformFeedbackVarying");
4360 if ((1 != size) || (GL_INT != type) || (0 != strcmp("result", name)))
4362 m_context.getTestContext().getLog()
4363 << tcu::TestLog::Message << "Error. Invalid GetTransformFeedbackVarying results."
4364 << " Size: " << size << " expected: " << 1 << ". Type: " << type << " expected: " << GL_INT
4365 << ". Name: " << name << " expected: result" << tcu::TestLog::EndMessage;
4367 TCU_FAIL("Invalid GetTransformFeedbackVarying results");
4371 /* Create/clean transform feedback buffer */
4372 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
4373 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
4375 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_size, &buffer_data[0], GL_DYNAMIC_COPY);
4376 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
4378 /* Set up transform feedback buffer */
4379 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_transform_feedback_buffer_id, 0 /* offset */,
4380 m_transform_feedback_buffer_size);
4381 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
4383 gl.beginTransformFeedback(captured_primitive);
4384 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
4388 case FRAGMENT_SHADER:
4391 gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
4392 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4394 gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height,
4395 GL_RED_INTEGER, GL_INT, &buffer_data[0]);
4396 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4398 /* Set up texture as color attachment 0 */
4399 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id);
4400 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
4402 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0 /* level */);
4403 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
4405 gl.viewport(0 /* x */, 0 /* y */, m_texture_width, m_texture_height);
4406 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
4410 case COMPUTE_SHADER:
4413 gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
4414 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4416 gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_width, m_texture_height,
4417 GL_RED_INTEGER, GL_INT, &buffer_data[0]);
4418 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4420 glw::GLint location = gl.getUniformLocation(program_id, "result");
4421 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4425 TCU_FAIL("Inactive uniform \"result\"");
4428 gl.uniform1i(location, 0 /* first image unit */);
4429 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4431 /* Bind texture to first image unit */
4432 gl.bindImageTexture(0 /* first image unit */, m_texture_id, 0 /* level */, GL_FALSE /* layered */,
4433 0 /* layer */, GL_WRITE_ONLY, GL_R32I);
4434 GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
4440 /** Unbind transform feedback buffer, framebuffer or image unit
4442 * @param shader_stage Tested shader stage id
4444 void GPUShaderFP64Test2::testEnd(shaderStage shader_stage) const
4446 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4448 switch (shader_stage)
4450 case GEOMETRY_SHADER:
4451 case TESS_CTRL_SHADER:
4452 case TESS_EVAL_SHADER:
4455 gl.endTransformFeedback();
4457 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
4461 case FRAGMENT_SHADER:
4463 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0 /* texture_id */,
4466 gl.bindTexture(GL_TEXTURE_2D, 0);
4468 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
4472 case COMPUTE_SHADER:
4474 gl.bindImageTexture(0 /* first image unit */, 0 /* texture_id */, 0 /* level */, GL_FALSE /* layered */,
4475 0 /* layer */, GL_WRITE_ONLY, GL_R32I);
4481 /** Initialize OpenGL objects for test
4484 void GPUShaderFP64Test2::testInit()
4486 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4488 /* The test is in 4.0 group. However:
4489 * - compute_shader is core since 4.3
4490 * - compute_shader require at least version 4.2 of GL */
4491 if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
4492 (true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
4494 m_pDispatchCompute = (arbDispatchComputeFunc)gl.dispatchCompute;
4497 /* Tesselation patch set up */
4498 gl.patchParameteri(GL_PATCH_VERTICES, 1);
4499 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
4502 gl.genFramebuffers(1, &m_framebuffer_id);
4503 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
4505 /* Prepare texture */
4506 gl.genTextures(1, &m_texture_id);
4507 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
4509 gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
4510 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4512 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R32I, m_texture_width, m_texture_height);
4513 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
4515 /* Prepare transform feedback buffer */
4516 gl.genBuffers(1, &m_transform_feedback_buffer_id);
4517 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
4519 /* Generate uniform buffer */
4520 gl.genBuffers(1, &m_uniform_buffer_id);
4521 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
4524 gl.genVertexArrays(1, &m_vertex_array_object_id);
4525 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
4527 gl.bindVertexArray(m_vertex_array_object_id);
4528 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
4531 /** Result verification, expected result is that whole buffer is filled with m_result_success
4533 * @param shader_stage Tested shader stage id
4535 bool GPUShaderFP64Test2::verifyResults(shaderStage shader_stage) const
4537 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4539 if ((FRAGMENT_SHADER == shader_stage) || (COMPUTE_SHADER == shader_stage))
4541 /* Verify contents of texture */
4543 /* Prepare storage for testure data */
4544 std::vector<glw::GLint> image_data;
4545 image_data.resize(m_texture_width * m_texture_height);
4547 /* Get texture contents */
4548 gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
4549 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4551 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]);
4552 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
4554 for (glw::GLuint y = 0; y < m_texture_width; ++y)
4556 for (glw::GLuint x = 0; x < m_texture_height; ++x)
4558 const glw::GLuint offset = y * m_texture_width + x;
4559 const glw::GLint value = image_data[offset];
4561 if (m_result_success != value)
4563 m_context.getTestContext().getLog()
4564 << tcu::TestLog::Message << "Error. Texture contents are wrong at (" << x << ", " << y << ")"
4565 << tcu::TestLog::EndMessage;
4576 /* Verify contents of transform feedback buffer */
4580 /* Get transform feedback data */
4581 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
4582 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
4584 glw::GLint* feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
4585 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
4587 for (glw::GLuint i = 0; i < m_n_captured_results; ++i)
4589 const glw::GLint value = feedback_data[i];
4591 if (m_result_success != value)
4593 m_context.getTestContext().getLog() << tcu::TestLog::Message
4594 << "Error. Transform feedback buffer contents are wrong at " << i
4595 << tcu::TestLog::EndMessage;
4602 /* Unmap transform feedback buffer */
4603 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
4604 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
4610 /* Definitions of static const fields declared in GPUShaderFP64Test3 */
4611 const glw::GLuint GPUShaderFP64Test3::m_result_failure = 0;
4612 const glw::GLuint GPUShaderFP64Test3::m_result_success = 1;
4614 const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_name = "UniformBlock";
4615 const glw::GLchar* GPUShaderFP64Test3::m_uniform_block_instance_name = "uniform_block";
4617 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_fs_out_fs_result = "fs_out_fs_result";
4618 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_gs_result = "gs_fs_gs_result";
4619 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tcs_result = "gs_fs_tcs_result";
4620 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_tes_result = "gs_fs_tes_result";
4621 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_gs_fs_vs_result = "gs_fs_vs_result";
4622 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_tcs_result = "tcs_tes_tcs_result";
4623 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tcs_tes_vs_result = "tcs_tes_vs_result";
4624 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tcs_result = "tes_gs_tcs_result";
4625 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_tes_result = "tes_gs_tes_result";
4626 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_tes_gs_vs_result = "tes_gs_vs_result";
4627 const glw::GLchar* GPUShaderFP64Test3::m_varying_name_vs_tcs_vs_result = "vs_tcs_vs_result";
4629 /* Definitions of static const fields declared in GPUShaderFP64Test3::programInfo */
4630 const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_offset = -1;
4631 const glw::GLint GPUShaderFP64Test3::programInfo::m_invalid_uniform_matrix_stride = -1;
4632 const glw::GLint GPUShaderFP64Test3::programInfo::m_non_matrix_uniform_matrix_stride = 0;
4636 * @param context Test context
4638 GPUShaderFP64Test3::GPUShaderFP64Test3(deqp::Context& context)
4639 : TestCase(context, "named_uniform_blocks",
4640 "Verifies usage of \"double precision\" floats in \"named uniform block\"")
4642 /* Nothing to be done */
4645 /** Deinitialize test
4648 void GPUShaderFP64Test3::deinit()
4650 /* GL entry points */
4651 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4653 /* Clean programs */
4654 m_packed_program.deinit(m_context);
4655 m_shared_program.deinit(m_context);
4656 m_std140_program.deinit(m_context);
4658 /* Clean frambuffer */
4659 if (0 != m_framebuffer_id)
4661 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
4662 gl.deleteFramebuffers(1, &m_framebuffer_id);
4664 m_framebuffer_id = 0;
4668 if (0 != m_color_texture_id)
4670 gl.bindTexture(GL_TEXTURE_2D, 0);
4671 gl.deleteTextures(1, &m_color_texture_id);
4673 m_color_texture_id = 0;
4677 if (0 != m_transform_feedback_buffer_id)
4679 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
4680 gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
4682 m_transform_feedback_buffer_id = 0;
4685 if (0 != m_uniform_buffer_id)
4687 gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
4688 gl.deleteBuffers(1, &m_uniform_buffer_id);
4690 m_uniform_buffer_id = 0;
4694 if (0 != m_vertex_array_object_id)
4696 gl.bindVertexArray(0);
4697 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
4699 m_vertex_array_object_id = 0;
4705 * @return tcu::TestNode::STOP
4707 tcu::TestNode::IterateResult GPUShaderFP64Test3::iterate()
4711 /* Check if extension is supported */
4712 if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
4714 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
4717 /* Initialize test */
4720 /* Test "packed" uniform buffer layout */
4721 if (false == test(PACKED))
4726 /* Test "shared" uniform buffer layout */
4727 if (false == test(SHARED))
4732 /* Test "std140" uniform buffer layout */
4733 if (false == test(STD140))
4741 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
4745 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4749 return tcu::TestNode::STOP;
4755 GPUShaderFP64Test3::programInfo::programInfo()
4756 : m_fragment_shader_id(0)
4757 , m_geometry_shader_id(0)
4758 , m_program_object_id(0)
4759 , m_tesselation_control_shader_id(0)
4760 , m_tesselation_evaluation_shader_id(0)
4761 , m_vertex_shader_id(0)
4763 , m_uniform_block_index(0)
4765 /* Nothing to be done here */
4770 * @param context Test context
4771 * @param shader_id Shader object id
4772 * @param shader_code Shader source code
4774 void GPUShaderFP64Test3::programInfo::compile(deqp::Context& context, glw::GLuint shader_id,
4775 const glw::GLchar* shader_code) const
4777 /* GL entry points */
4778 const glw::Functions& gl = context.getRenderContext().getFunctions();
4780 /* Compilation status */
4781 glw::GLint status = GL_FALSE;
4783 /* Set source code */
4784 gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
4785 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
4788 gl.compileShader(shader_id);
4789 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
4791 /* Get compilation status */
4792 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
4793 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
4795 /* Log compilation error */
4796 if (GL_TRUE != status)
4798 glw::GLint length = 0;
4799 std::vector<glw::GLchar> message;
4801 /* Error log length */
4802 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
4803 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
4805 /* Prepare storage */
4806 message.resize(length);
4809 gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
4810 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
4813 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
4814 << &message[0] << "\nShader source\n"
4815 << shader_code << tcu::TestLog::EndMessage;
4817 TCU_FAIL("Failed to compile shader");
4821 /** Cleans program and attached shaders
4823 * @param context Test context
4825 void GPUShaderFP64Test3::programInfo::deinit(deqp::Context& context)
4827 /* GL entry points */
4828 const glw::Functions& gl = context.getRenderContext().getFunctions();
4830 /* Restore default program */
4833 /* Clean program object */
4834 if (0 != m_program_object_id)
4836 gl.deleteProgram(m_program_object_id);
4837 m_program_object_id = 0;
4841 if (0 != m_fragment_shader_id)
4843 gl.deleteShader(m_fragment_shader_id);
4844 m_fragment_shader_id = 0;
4847 if (0 != m_geometry_shader_id)
4849 gl.deleteShader(m_geometry_shader_id);
4850 m_geometry_shader_id = 0;
4853 if (0 != m_tesselation_control_shader_id)
4855 gl.deleteShader(m_tesselation_control_shader_id);
4856 m_tesselation_control_shader_id = 0;
4859 if (0 != m_tesselation_evaluation_shader_id)
4861 gl.deleteShader(m_tesselation_evaluation_shader_id);
4862 m_tesselation_evaluation_shader_id = 0;
4865 if (0 != m_vertex_shader_id)
4867 gl.deleteShader(m_vertex_shader_id);
4868 m_vertex_shader_id = 0;
4872 /** Build program and query for uniform layout
4874 * @param context Test context
4875 * @param uniform_details Collection of uniform details
4876 * @param fragment_shader_code Fragment shader source code
4877 * @param geometry_shader_code Geometry shader source code
4878 * @param tesselation_control_shader_code Tesselation control shader source code
4879 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
4880 * @param vertex_shader_code Vertex shader source code
4882 void GPUShaderFP64Test3::programInfo::init(deqp::Context& context, const std::vector<uniformDetails> uniform_details,
4883 const glw::GLchar* fragment_shader_code,
4884 const glw::GLchar* geometry_shader_code,
4885 const glw::GLchar* tesselation_control_shader_code,
4886 const glw::GLchar* tesselation_evaluation_shader_code,
4887 const glw::GLchar* vertex_shader_code)
4889 /* GL entry points */
4890 const glw::Functions& gl = context.getRenderContext().getFunctions();
4892 /* Names of varyings to be captured with transform feedback */
4893 static const glw::GLchar* varying_names[] = { m_varying_name_gs_fs_gs_result, m_varying_name_gs_fs_tcs_result,
4894 m_varying_name_gs_fs_tes_result, m_varying_name_gs_fs_vs_result };
4895 static const glw::GLuint n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]);
4897 /* Create shader objects */
4898 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
4899 m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
4900 m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
4901 m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
4902 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
4903 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
4905 /* Create program object */
4906 m_program_object_id = gl.createProgram();
4907 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
4909 /* Set up names of varyings to be captured with transform feedback */
4910 gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
4911 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
4913 /* Compile shaders */
4914 compile(context, m_fragment_shader_id, fragment_shader_code);
4915 compile(context, m_geometry_shader_id, geometry_shader_code);
4916 compile(context, m_tesselation_control_shader_id, tesselation_control_shader_code);
4917 compile(context, m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
4918 compile(context, m_vertex_shader_id, vertex_shader_code);
4923 /* Inspect program object */
4924 /* Get index of named uniform block */
4925 m_uniform_block_index = gl.getUniformBlockIndex(m_program_object_id, m_uniform_block_name);
4926 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformBlockIndex");
4928 if (GL_INVALID_INDEX == m_uniform_block_index)
4930 TCU_FAIL("Unifom block is inactive");
4933 /* Get size of named uniform block */
4934 gl.getActiveUniformBlockiv(m_program_object_id, m_uniform_block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &m_buffer_size);
4935 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformBlockiv");
4937 if (0 == m_buffer_size)
4939 TCU_FAIL("Unifom block size is 0");
4942 /* Get information about "double precision" uniforms */
4943 for (std::vector<uniformDetails>::const_iterator it = uniform_details.begin(), end = uniform_details.end();
4946 const glw::GLchar* uniform_name = 0;
4947 std::string uniform_name_str;
4948 std::stringstream uniform_name_stream;
4949 glw::GLuint index = 0;
4950 glw::GLint offset = 0;
4951 glw::GLint matrix_stride = 0;
4953 /* Uniform name = UNIFORM_BLOCK_NAME.UNIFORM_NAME */
4954 uniform_name_stream << m_uniform_block_name << "." << it->m_name;
4956 uniform_name_str = uniform_name_stream.str();
4957 uniform_name = uniform_name_str.c_str();
4959 /* Get index of uniform */
4960 gl.getUniformIndices(m_program_object_id, 1 /* count */, &uniform_name, &index);
4961 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformIndices");
4963 if (GL_INVALID_INDEX == index)
4965 TCU_FAIL("Unifom is inactive");
4968 /* Get offset of uniform */
4969 gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_OFFSET, &offset);
4970 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
4972 if (m_invalid_uniform_offset == offset)
4974 TCU_FAIL("Unifom has invalid offset");
4977 m_uniform_offsets.push_back(offset);
4979 /* Get matrix stride of uniform */
4980 gl.getActiveUniformsiv(m_program_object_id, 1 /* count */, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
4981 GLU_EXPECT_NO_ERROR(gl.getError(), "GetActiveUniformsiv");
4983 if (m_invalid_uniform_matrix_stride == offset)
4985 TCU_FAIL("Unifom has invalid matrix stride");
4988 m_uniform_matrix_strides.push_back(matrix_stride);
4992 /** Attach shaders and link program
4994 * @param context Test context
4996 void GPUShaderFP64Test3::programInfo::link(deqp::Context& context) const
4998 /* GL entry points */
4999 const glw::Functions& gl = context.getRenderContext().getFunctions();
5002 glw::GLint status = GL_FALSE;
5004 /* Attach shaders */
5005 gl.attachShader(m_program_object_id, m_fragment_shader_id);
5006 gl.attachShader(m_program_object_id, m_geometry_shader_id);
5007 gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
5008 gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
5009 gl.attachShader(m_program_object_id, m_vertex_shader_id);
5010 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
5013 gl.linkProgram(m_program_object_id);
5014 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
5016 /* Get link status */
5017 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
5018 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
5020 /* Log link error */
5021 if (GL_TRUE != status)
5023 glw::GLint length = 0;
5024 std::vector<glw::GLchar> message;
5026 /* Get error log length */
5027 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
5028 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
5030 message.resize(length);
5033 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
5034 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
5037 context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
5038 << &message[0] << tcu::TestLog::EndMessage;
5040 TCU_FAIL("Failed to link program");
5044 /** Returns "predefined" values that will be used to fill uniform data
5046 * @param type_ordinal Ordinal number of "double precision" uniform type
5047 * @param element Index of element in uniform
5049 * @return "Predefined" value
5051 glw::GLdouble GPUShaderFP64Test3::getExpectedValue(glw::GLuint type_ordinal, glw::GLuint element) const
5053 return m_base_type_ordinal + (13.0 * (glw::GLdouble)type_ordinal) +
5054 ((m_base_element - (glw::GLdouble)element) / 4.0);
5057 /** Returns a reference of programInfo instance specific for given buffer layout
5059 * @param uniform_data_layout Buffer layout
5061 * @return Reference to an instance of programInfo
5063 const GPUShaderFP64Test3::programInfo& GPUShaderFP64Test3::getProgramInfo(uniformDataLayout uniform_data_layout) const
5065 const programInfo* program_info = 0;
5067 switch (uniform_data_layout)
5071 program_info = &m_packed_program;
5077 program_info = &m_shared_program;
5083 program_info = &m_std140_program;
5088 return *program_info;
5091 /** Get "name" of buffer layout
5093 * @param uniform_data_layout Buffer layout
5095 * @return "Name" of layout
5097 const glw::GLchar* GPUShaderFP64Test3::getUniformLayoutName(uniformDataLayout uniform_data_layout) const
5099 const glw::GLchar* layout = "";
5101 switch (uniform_data_layout)
5117 /** Prepare programInfo instance for specific buffer layout
5119 * @param program_info Instance of programInfo
5120 * @param uniform_data_layout Buffer layout
5122 void GPUShaderFP64Test3::prepareProgram(programInfo& program_info, uniformDataLayout uniform_data_layout) const
5124 /* Storage for shader source code */
5125 std::stringstream fragment_shader_code;
5126 std::stringstream geometry_shader_code;
5127 std::stringstream tess_control_shader_code;
5128 std::stringstream tess_eval_shader_code;
5129 std::stringstream vertex_shader_code;
5131 /* Write preambles */
5132 writePreamble(fragment_shader_code, FRAGMENT_SHADER);
5133 writePreamble(geometry_shader_code, GEOMETRY_SHADER);
5134 writePreamble(tess_control_shader_code, TESS_CONTROL_SHADER);
5135 writePreamble(tess_eval_shader_code, TESS_EVAL_SHADER);
5136 writePreamble(vertex_shader_code, VERTEX_SHADER);
5138 /* Write definition of named uniform block */
5139 writeUniformBlock(fragment_shader_code, uniform_data_layout);
5140 writeUniformBlock(geometry_shader_code, uniform_data_layout);
5141 writeUniformBlock(tess_control_shader_code, uniform_data_layout);
5142 writeUniformBlock(tess_eval_shader_code, uniform_data_layout);
5143 writeUniformBlock(vertex_shader_code, uniform_data_layout);
5145 /* Write definitions of varyings */
5146 writeVaryingDeclarations(fragment_shader_code, FRAGMENT_SHADER);
5147 writeVaryingDeclarations(geometry_shader_code, GEOMETRY_SHADER);
5148 writeVaryingDeclarations(tess_control_shader_code, TESS_CONTROL_SHADER);
5149 writeVaryingDeclarations(tess_eval_shader_code, TESS_EVAL_SHADER);
5150 writeVaryingDeclarations(vertex_shader_code, VERTEX_SHADER);
5152 /* Write main routine */
5153 writeMainBody(fragment_shader_code, FRAGMENT_SHADER);
5154 writeMainBody(geometry_shader_code, GEOMETRY_SHADER);
5155 writeMainBody(tess_control_shader_code, TESS_CONTROL_SHADER);
5156 writeMainBody(tess_eval_shader_code, TESS_EVAL_SHADER);
5157 writeMainBody(vertex_shader_code, VERTEX_SHADER);
5159 /* Init programInfo instance */
5160 program_info.init(m_context, m_uniform_details, fragment_shader_code.str().c_str(),
5161 geometry_shader_code.str().c_str(), tess_control_shader_code.str().c_str(),
5162 tess_eval_shader_code.str().c_str(), vertex_shader_code.str().c_str());
5165 /** Prepare uniform buffer
5167 * @param program_info Instance of programInfo
5168 * @param verify_offsets If uniform offsets should be verified against expected values
5170 * @return false if uniform offsets verification result is failure, true otherwise
5172 bool GPUShaderFP64Test3::prepareUniformBuffer(const programInfo& program_info, bool verify_offsets) const
5174 const glw::GLuint buffer_size = program_info.m_buffer_size;
5175 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5176 bool offset_verification_result = true;
5177 glw::GLuint type_ordinal = 1;
5178 std::vector<uniformDetails>::const_iterator it_uniform_details = m_uniform_details.begin();
5179 std::vector<glw::GLint>::const_iterator it_uniform_offsets = program_info.m_uniform_offsets.begin();
5180 std::vector<glw::GLint>::const_iterator it_uniform_matrix_strides = program_info.m_uniform_matrix_strides.begin();
5182 /* Prepare storage for uniform buffer data */
5183 std::vector<glw::GLubyte> buffer_data;
5184 buffer_data.resize(buffer_size);
5186 /* For each "double precision" uniform */
5187 for (/* start conditions already set up */; m_uniform_details.end() != it_uniform_details;
5188 ++it_uniform_details, ++it_uniform_offsets, ++it_uniform_matrix_strides, ++type_ordinal)
5190 const glw::GLint matrix_stride = *it_uniform_matrix_strides;
5191 const glw::GLuint n_columns = it_uniform_details->m_n_columns;
5192 const glw::GLuint n_elements = it_uniform_details->m_n_elements;
5193 const glw::GLuint column_length = n_elements / n_columns;
5194 const glw::GLint uniform_offset = *it_uniform_offsets;
5196 /* For each element of uniform */
5197 for (glw::GLuint element = 0; element < n_elements; ++element)
5199 const glw::GLuint column = element / column_length;
5200 const glw::GLuint column_elem = element % column_length;
5201 const glw::GLdouble value = getExpectedValue(type_ordinal, element);
5202 const glw::GLuint value_offset =
5203 static_cast<glw::GLuint>(uniform_offset + column * matrix_stride + column_elem * sizeof(glw::GLdouble));
5205 glw::GLdouble* value_dst = (glw::GLdouble*)&buffer_data[value_offset];
5211 /* Uniform offset verification */
5212 if (true == verify_offsets)
5214 const glw::GLint expected_offset = it_uniform_details->m_expected_std140_offset;
5216 if (expected_offset != uniform_offset)
5218 if (true == offset_verification_result)
5220 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage;
5223 m_context.getTestContext().getLog()
5224 << tcu::TestLog::Message << "Uniform: " << it_uniform_details->m_name
5225 << " has offset: " << uniform_offset << ". Expected offset: " << expected_offset
5226 << tcu::TestLog::EndMessage;
5228 offset_verification_result = false;
5233 /* Update uniform buffer with prepared data */
5234 gl.bindBuffer(GL_UNIFORM_BUFFER, m_uniform_buffer_id);
5235 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
5237 gl.bufferData(GL_UNIFORM_BUFFER, buffer_size, &buffer_data[0], GL_STATIC_DRAW);
5238 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
5240 /* Bind uniform buffer as data source for named uniform block */
5241 gl.bindBufferRange(GL_UNIFORM_BUFFER, 0 /* index */, m_uniform_buffer_id, 0, buffer_size);
5242 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
5244 gl.uniformBlockBinding(program_info.m_program_object_id, program_info.m_uniform_block_index, 0 /* binding */);
5245 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformBlockBinding");
5248 return offset_verification_result;
5251 /** Prepare data, execute draw call and verify results
5253 * @param uniform_data_layout
5255 * @return true if test pass, false otherwise
5257 bool GPUShaderFP64Test3::test(uniformDataLayout uniform_data_layout) const
5259 bool are_offsets_verified = (STD140 == uniform_data_layout);
5260 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5261 bool offset_verification_result = true;
5262 const programInfo& program_info = getProgramInfo(uniform_data_layout);
5265 /* Set up program */
5266 gl.useProgram(program_info.m_program_object_id);
5267 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
5269 /* Prepare uniform buffer */
5270 offset_verification_result = prepareUniformBuffer(program_info, are_offsets_verified);
5272 if (true == are_offsets_verified && false == offset_verification_result)
5274 /* Offsets verification failure was already reported, add info about buffer layout */
5275 m_context.getTestContext().getLog() << tcu::TestLog::Message
5276 << "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout)
5277 << tcu::TestLog::EndMessage;
5282 /* Set up transform feedback buffer */
5283 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_transform_feedback_buffer_id, 0, 4 * sizeof(glw::GLint));
5284 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
5286 /* Begin transform feedback */
5287 gl.beginTransformFeedback(GL_POINTS);
5288 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
5290 /* Execute draw call for singe vertex */
5291 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
5292 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
5294 /* Stop transform feedback */
5295 gl.endTransformFeedback();
5296 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
5298 /* Verify results */
5299 if (false == verifyResults())
5301 /* Result verificatioon failure was already reported, add info about layout */
5302 m_context.getTestContext().getLog() << tcu::TestLog::Message
5303 << "Uniform buffer layout: " << getUniformLayoutName(uniform_data_layout)
5304 << tcu::TestLog::EndMessage;
5313 void GPUShaderFP64Test3::testInit()
5315 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5317 /* Uniform block declaration with std140 offsets calculated
5318 * | align | loc_req | begins | ends | offset in bytes | imp |
5319 * ivec3 dummy1[3] | 4 | 12 | 0 | 12 | 0 | |
5320 * double double_value | 2 | 2 | 12 | 14 | 48 | XXX |
5321 * bool dummy2 | 1 | 1 | 14 | 15 | 56 | |
5322 * dvec2 dvec2_value | 4 | 4 | 16 | 20 | 64 | XXX |
5323 * bvec3 dummy3 | 4 | 4 | 20 | 24 | 80 | |
5324 * dvec3 dvec3_value | 8 | 8 | 24 | 32 | 96 | XXX |
5325 * int dummy4[3] | 4 | 12 | 32 | 44 | 128 | |
5326 * dvec4 dvec4_value | 8 | 8 | 48 | 56 | 192 | XXX |
5327 * bool dummy5 | 1 | 1 | 56 | 57 | 224 | |
5328 * bool dummy6[2] | 4 | 8 | 60 | 68 | 240 | |
5329 * dmat2 dmat2_value | 4 | 8 | 68 | 76 | 272 | XXX |
5330 * dmat3 dmat3_value | 8 | 24 | 80 | 104 | 320 | XXX |
5331 * bool dummy7 | 1 | 1 | 104 | 105 | 416 | |
5332 * dmat4 dmat4_value | 8 | 32 | 112 | 144 | 448 | XXX |
5333 * dmat2x3 dmat2x3_value | 8 | 16 | 144 | 160 | 576 | XXX |
5334 * uvec3 dummy8 | 4 | 4 | 160 | 164 | 640 | |
5335 * dmat2x4 dmat2x4_value | 8 | 16 | 168 | 184 | 672 | XXX |
5336 * dmat3x2 dmat3x2_value | 4 | 12 | 184 | 196 | 736 | XXX |
5337 * bool dummy9 | 1 | 1 | 196 | 197 | 784 | |
5338 * dmat3x4 dmat3x4_value | 8 | 24 | 200 | 224 | 800 | XXX |
5339 * int dummy10 | 1 | 1 | 224 | 225 | 896 | |
5340 * dmat4x2 dmat4x2_value | 4 | 16 | 228 | 244 | 912 | XXX |
5341 * dmat4x3 dmat4x3_value | 8 | 32 | 248 | 280 | 992 | XXX |
5344 /* Prepare "double precision" unfiorms' details */
5345 m_uniform_details.push_back(uniformDetails(48 /* off */, "double_value" /* name */, 1 /* n_columns */,
5346 1 /* n_elements */, "double" /* type_name */));
5347 m_uniform_details.push_back(uniformDetails(64 /* off */, "dvec2_value" /* name */, 1 /* n_columns */,
5348 2 /* n_elements */, "dvec2" /* type_name */));
5349 m_uniform_details.push_back(uniformDetails(96 /* off */, "dvec3_value" /* name */, 1 /* n_columns */,
5350 3 /* n_elements */, "dvec3" /* type_name */));
5351 m_uniform_details.push_back(uniformDetails(192 /* off */, "dvec4_value" /* name */, 1 /* n_columns */,
5352 4 /* n_elements */, "dvec4" /* type_name */));
5353 m_uniform_details.push_back(uniformDetails(272 /* off */, "dmat2_value" /* name */, 2 /* n_columns */,
5354 4 /* n_elements */, "dmat2" /* type_name */));
5355 m_uniform_details.push_back(uniformDetails(320 /* off */, "dmat3_value" /* name */, 3 /* n_columns */,
5356 9 /* n_elements */, "dmat3" /* type_name */));
5357 m_uniform_details.push_back(uniformDetails(448 /* off */, "dmat4_value" /* name */, 4 /* n_columns */,
5358 16 /* n_elements */, "dmat4" /* type_name */));
5359 m_uniform_details.push_back(uniformDetails(576 /* off */, "dmat2x3_value" /* name */, 2 /* n_columns */,
5360 6 /* n_elements */, "dmat2x3" /* type_name */));
5361 m_uniform_details.push_back(uniformDetails(672 /* off */, "dmat2x4_value" /* name */, 2 /* n_columns */,
5362 8 /* n_elements */, "dmat2x4" /* type_name */));
5363 m_uniform_details.push_back(uniformDetails(736 /* off */, "dmat3x2_value" /* name */, 3 /* n_columns */,
5364 6 /* n_elements */, "dmat3x2" /* type_name */));
5365 m_uniform_details.push_back(uniformDetails(800 /* off */, "dmat3x4_value" /* name */, 3 /* n_columns */,
5366 12 /* n_elements */, "dmat3x4" /* type_name */));
5367 m_uniform_details.push_back(uniformDetails(912 /* off */, "dmat4x2_value" /* name */, 4 /* n_columns */,
5368 8 /* n_elements */, "dmat4x2" /* type_name */));
5369 m_uniform_details.push_back(uniformDetails(992 /* off */, "dmat4x3_value" /* name */, 4 /* n_columns */,
5370 12 /* n_elements */, "dmat4x3" /* type_name */));
5372 /* Get random values for getExpectedValue */
5373 m_base_element = (glw::GLdouble)(rand() % 13);
5374 m_base_type_ordinal = (glw::GLdouble)(rand() % 213);
5376 /* Prepare programInfos for all buffer layouts */
5377 prepareProgram(m_packed_program, PACKED);
5378 prepareProgram(m_shared_program, SHARED);
5379 prepareProgram(m_std140_program, STD140);
5381 /* Generate buffers */
5382 gl.genBuffers(1, &m_transform_feedback_buffer_id);
5383 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
5385 gl.genBuffers(1, &m_uniform_buffer_id);
5386 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
5388 /* Prepare transform feedback buffer */
5389 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
5390 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
5392 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), 0 /* data */, GL_DYNAMIC_COPY);
5393 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
5395 /* Prepare texture for color attachment 0 */
5396 gl.genTextures(1, &m_color_texture_id);
5397 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
5399 gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id);
5400 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
5402 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_R32I, 1 /* width */, 1 /* height */);
5403 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
5405 /* Prepare FBO with color attachment 0 */
5406 gl.genFramebuffers(1, &m_framebuffer_id);
5407 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
5409 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id);
5410 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
5412 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture_id,
5414 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
5416 gl.viewport(0 /* x */, 0 /* y */, 1 /* width */, 1 /* height */);
5417 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
5420 gl.genVertexArrays(1, &m_vertex_array_object_id);
5421 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
5423 gl.bindVertexArray(m_vertex_array_object_id);
5424 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
5426 /* Tesselation patch set up */
5427 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5428 GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri");
5431 /** Verify contents of transform feedback buffer and framebuffer's color attachment 0
5433 * @return true if all values are as expected, false otherwise
5435 bool GPUShaderFP64Test3::verifyResults() const
5437 glw::GLint* feedback_data = 0;
5438 bool fragment_shader_result = false;
5439 bool geometry_shader_result = false;
5440 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5441 bool tess_ctrl_shader_result = false;
5442 bool tess_eval_shader_result = false;
5443 bool vertex_shader_result = false;
5445 /* Prepare storage for testure data */
5446 std::vector<glw::GLint> image_data;
5447 image_data.resize(1);
5449 /* Get texture contents */
5450 gl.bindTexture(GL_TEXTURE_2D, m_color_texture_id);
5451 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
5453 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RED_INTEGER, GL_INT, &image_data[0]);
5454 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
5456 /* Get transform feedback data */
5457 feedback_data = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
5458 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
5460 /* Verify results */
5461 fragment_shader_result = (m_result_success == image_data[0]);
5462 geometry_shader_result = (m_result_success == feedback_data[0]);
5463 tess_ctrl_shader_result = (m_result_success == feedback_data[1]);
5464 tess_eval_shader_result = (m_result_success == feedback_data[2]);
5465 vertex_shader_result = (m_result_success == feedback_data[3]);
5467 /* Unmap transform feedback buffer */
5468 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
5469 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
5472 if (true != (fragment_shader_result && geometry_shader_result && tess_ctrl_shader_result &&
5473 tess_eval_shader_result && vertex_shader_result))
5475 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error" << tcu::TestLog::EndMessage;
5477 m_context.getTestContext().getLog() << tcu::TestLog::Message
5478 << "Vertex shader stage result: " << vertex_shader_result
5479 << tcu::TestLog::EndMessage;
5481 m_context.getTestContext().getLog() << tcu::TestLog::Message
5482 << "Tesselation control shader stage result: " << tess_ctrl_shader_result
5483 << tcu::TestLog::EndMessage;
5485 m_context.getTestContext().getLog() << tcu::TestLog::Message
5486 << "Tesselation evaluation shader stage result: " << tess_eval_shader_result
5487 << tcu::TestLog::EndMessage;
5489 m_context.getTestContext().getLog() << tcu::TestLog::Message
5490 << "Geometry shader stage result: " << geometry_shader_result
5491 << tcu::TestLog::EndMessage;
5493 m_context.getTestContext().getLog() << tcu::TestLog::Message
5494 << "Fragment shader stage result: " << fragment_shader_result
5495 << tcu::TestLog::EndMessage;
5505 /** Write main routine of <shader_stage> shader to stream
5507 * @param stream Output stream with source code of shader
5508 * @param shader_stage Shader stage
5510 void GPUShaderFP64Test3::writeMainBody(std::ostream& stream, shaderStage shader_stage) const
5512 glw::GLuint type_ordinal = 1;
5513 const glw::GLchar* varying_name = "";
5515 /* Select name for varying that will hold result of "that" shader_stage */
5516 switch (shader_stage)
5518 case FRAGMENT_SHADER:
5519 varying_name = m_varying_name_fs_out_fs_result;
5521 case GEOMETRY_SHADER:
5522 varying_name = m_varying_name_gs_fs_gs_result;
5524 case TESS_CONTROL_SHADER:
5525 varying_name = m_varying_name_tcs_tes_tcs_result;
5527 case TESS_EVAL_SHADER:
5528 varying_name = m_varying_name_tes_gs_tes_result;
5531 varying_name = m_varying_name_vs_tcs_vs_result;
5536 stream << "void main()\n"
5539 /* Tesselation levels output */
5540 if (TESS_CONTROL_SHADER == shader_stage)
5542 stream << "gl_TessLevelOuter[0] = 1.0;\n"
5543 "gl_TessLevelOuter[1] = 1.0;\n"
5544 "gl_TessLevelOuter[2] = 1.0;\n"
5545 "gl_TessLevelOuter[3] = 1.0;\n"
5546 "gl_TessLevelInner[0] = 1.0;\n"
5547 "gl_TessLevelInner[1] = 1.0;\n"
5551 /* For each "double precision" uniform
5553 * [else] if (TYPE_NAME(PREDIFINED_VALUES) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME)
5555 * VARYING_NAME = m_result_failure;
5558 for (std::vector<uniformDetails>::const_iterator it = m_uniform_details.begin(), end = m_uniform_details.end();
5559 end != it; ++it, ++type_ordinal)
5563 /* First comparison is done with if, next with else if */
5564 if (1 != type_ordinal)
5569 /* if (TYPE_NAME( */
5570 stream << "if (" << it->m_type_name << "(";
5572 /* PREDIFINED_VALUES */
5573 for (glw::GLuint element = 0; element < it->m_n_elements; ++element)
5575 stream << getExpectedValue(type_ordinal, element);
5577 /* Separate with comma */
5578 if (it->m_n_elements != element + 1)
5585 * ) != NAMED_UNIFORM_BLOCK_NAME.UNIFORM_NAME)
5589 stream << ") != " << m_uniform_block_instance_name << "." << it->m_name << ")\n"
5594 /* Tesselation control outputs have to be arrays indexed with gl_InvocationID */
5595 if (TESS_CONTROL_SHADER == shader_stage)
5597 stream << "[gl_InvocationID]";
5601 * = m_result_failure;
5604 stream << " = " << m_result_failure << ";\n"
5608 /* If all comparisons are ok
5612 * VARYING_NAME = m_result_success;
5626 /* Tesselation control outputs have to be arrays indexed with gl_InvocationID */
5627 if (TESS_CONTROL_SHADER == shader_stage)
5629 stream << "[gl_InvocationID]";
5633 * = m_result_success;
5637 stream << " = " << m_result_success << ";\n"
5641 /* For each pair of "input/output" varyings
5643 * OUTPUT_VARYING_NAME = INPUT_VARYING_NAME;
5645 writeVaryingPassthrough(stream, shader_stage);
5647 /* Geometry shader have to emit vertex */
5648 if (GEOMETRY_SHADER == shader_stage)
5651 "gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"
5653 "EndPrimitive();\n";
5656 /* Close scope of main */
5660 /** Write shader preamble to stream
5662 * @param stream Output stream with source code of shader
5663 * @param shader_stage Shader stage
5665 void GPUShaderFP64Test3::writePreamble(std::ostream& stream, shaderStage shader_stage) const
5667 stream << "#version 400 core\n"
5669 "precision highp float;\n"
5672 switch (shader_stage)
5674 case FRAGMENT_SHADER:
5676 case GEOMETRY_SHADER:
5677 stream << "layout(points) in;\n"
5678 "layout(points, max_vertices = 1) out;\n"
5681 case TESS_CONTROL_SHADER:
5682 stream << "layout(vertices = 1) out;\n"
5685 case TESS_EVAL_SHADER:
5686 stream << "layout(isolines, point_mode) in;\n"
5694 /** Write name uniform blcok definition with specific layout to stream
5696 * @param stream Output stream with source code of shader
5697 * @param uniform_data_layout Buffer layout
5699 void GPUShaderFP64Test3::writeUniformBlock(std::ostream& stream, uniformDataLayout uniform_data_layout) const
5701 const glw::GLchar* layout = getUniformLayoutName(uniform_data_layout);
5703 stream << "layout(" << layout << ") uniform " << m_uniform_block_name << "\n"
5705 " ivec3 dummy1[3];\n"
5706 " double double_value;\n"
5708 " dvec2 dvec2_value;\n"
5710 " dvec3 dvec3_value;\n"
5712 " dvec4 dvec4_value;\n"
5714 " bool dummy6[2];\n"
5715 " dmat2 dmat2_value;\n"
5716 " dmat3 dmat3_value;\n"
5718 " dmat4 dmat4_value;\n"
5719 " dmat2x3 dmat2x3_value;\n"
5721 " dmat2x4 dmat2x4_value;\n"
5722 " dmat3x2 dmat3x2_value;\n"
5724 " dmat3x4 dmat3x4_value;\n"
5726 " dmat4x2 dmat4x2_value;\n"
5727 " dmat4x3 dmat4x3_value;\n"
5729 << m_uniform_block_instance_name << ";\n";
5734 /** Write definitions of varyings specific for given <shader_stage> to stream
5736 * @param stream Output stream with source code of shader
5737 * @param shader_stage Shader stage
5739 void GPUShaderFP64Test3::writeVaryingDeclarations(std::ostream& stream, shaderStage shader_stage) const
5741 static const glw::GLchar* const varying_type = "int";
5743 switch (shader_stage)
5745 case FRAGMENT_SHADER:
5748 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n";
5749 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n";
5750 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n";
5751 stream << "flat in " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n";
5756 stream << "layout (location = 0) out " << varying_type << " " << m_varying_name_fs_out_fs_result << ";\n";
5760 case GEOMETRY_SHADER:
5763 stream << "in " << varying_type << " " << m_varying_name_tes_gs_tcs_result << "[];\n";
5764 stream << "in " << varying_type << " " << m_varying_name_tes_gs_tes_result << "[];\n";
5765 stream << "in " << varying_type << " " << m_varying_name_tes_gs_vs_result << "[];\n";
5770 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_gs_result << ";\n";
5771 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tcs_result << ";\n";
5772 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_tes_result << ";\n";
5773 stream << "flat out " << varying_type << " " << m_varying_name_gs_fs_vs_result << ";\n";
5777 case TESS_CONTROL_SHADER:
5780 stream << "in " << varying_type << " " << m_varying_name_vs_tcs_vs_result << "[];\n";
5785 stream << "out " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n";
5786 stream << "out " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n";
5790 case TESS_EVAL_SHADER:
5793 stream << "in " << varying_type << " " << m_varying_name_tcs_tes_tcs_result << "[];\n";
5794 stream << "in " << varying_type << " " << m_varying_name_tcs_tes_vs_result << "[];\n";
5799 stream << "out " << varying_type << " " << m_varying_name_tes_gs_tcs_result << ";\n";
5800 stream << "out " << varying_type << " " << m_varying_name_tes_gs_tes_result << ";\n";
5801 stream << "out " << varying_type << " " << m_varying_name_tes_gs_vs_result << ";\n";
5808 stream << "out " << varying_type << " " << m_varying_name_vs_tcs_vs_result << ";\n";
5816 /** Write passthrough code of "input/output" varying pairs to stream
5818 * @param stream Output stream with source code of shader
5819 * @param shader_stage Shader stage
5821 void GPUShaderFP64Test3::writeVaryingPassthrough(std::ostream& stream, shaderStage shader_stage) const
5823 switch (shader_stage)
5825 case FRAGMENT_SHADER:
5828 case GEOMETRY_SHADER:
5830 stream << " " << m_varying_name_gs_fs_tcs_result << " = " << m_varying_name_tes_gs_tcs_result << "[0];\n";
5831 stream << " " << m_varying_name_gs_fs_tes_result << " = " << m_varying_name_tes_gs_tes_result << "[0];\n";
5832 stream << " " << m_varying_name_gs_fs_vs_result << " = " << m_varying_name_tes_gs_vs_result << "[0];\n";
5836 case TESS_CONTROL_SHADER:
5838 stream << " " << m_varying_name_tcs_tes_vs_result
5839 << "[gl_InvocationID] = " << m_varying_name_vs_tcs_vs_result << "[0];\n";
5843 case TESS_EVAL_SHADER:
5845 stream << " " << m_varying_name_tes_gs_tcs_result << " = " << m_varying_name_tcs_tes_tcs_result << "[0];\n";
5846 stream << " " << m_varying_name_tes_gs_vs_result << " = " << m_varying_name_tcs_tes_vs_result << "[0];\n";
5856 /** Constructor. Sets all uniform locations to -1 and sets all
5859 GPUShaderFP64Test4::_data::_data()
5861 memset(&uniform_double, 0, sizeof(uniform_double));
5862 memset(uniform_dvec2, 0, sizeof(uniform_dvec2));
5863 memset(uniform_dvec2_arr, 0, sizeof(uniform_dvec2_arr));
5864 memset(uniform_dvec3, 0, sizeof(uniform_dvec3));
5865 memset(uniform_dvec3_arr, 0, sizeof(uniform_dvec3_arr));
5866 memset(uniform_dvec4, 0, sizeof(uniform_dvec4));
5867 memset(uniform_dvec4_arr, 0, sizeof(uniform_dvec4_arr));
5869 uniform_location_double = -1;
5870 uniform_location_double_arr[0] = -1;
5871 uniform_location_double_arr[1] = -1;
5872 uniform_location_dvec2 = -1;
5873 uniform_location_dvec2_arr[0] = -1;
5874 uniform_location_dvec2_arr[1] = -1;
5875 uniform_location_dvec3 = -1;
5876 uniform_location_dvec3_arr[0] = -1;
5877 uniform_location_dvec3_arr[1] = -1;
5878 uniform_location_dvec4 = -1;
5879 uniform_location_dvec4_arr[0] = -1;
5880 uniform_location_dvec4_arr[1] = -1;
5885 * @param context Rendering context.
5887 GPUShaderFP64Test4::GPUShaderFP64Test4(deqp::Context& context)
5888 : TestCase(context, "state_query", "Verifies glGet*() calls, as well as \"program interface query\"-specific tools"
5889 " report correct properties of & values assigned to double-precision uniforms.")
5890 , m_has_test_passed(true)
5891 , m_uniform_name_buffer(0)
5901 /* Left blank intentionally */
5904 /** Deinitializes all GL objects, as well as releases all bufers, that may
5905 * have beenallocated or created during test execution.
5907 void GPUShaderFP64Test4::deinit()
5909 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5913 gl.deleteShader(m_cs_id);
5920 gl.deleteShader(m_fs_id);
5927 gl.deleteShader(m_gs_id);
5932 if (m_po_cs_id != 0)
5934 gl.deleteProgram(m_po_cs_id);
5939 if (m_po_noncs_id != 0)
5941 gl.deleteProgram(m_po_noncs_id);
5948 gl.deleteShader(m_tc_id);
5955 gl.deleteShader(m_te_id);
5960 if (m_uniform_name_buffer != DE_NULL)
5962 delete[] m_uniform_name_buffer;
5964 m_uniform_name_buffer = DE_NULL;
5969 gl.deleteShader(m_vs_id);
5975 /** Generates double-precision values for all uniforms defined for all program objects
5978 * This function DOES NOT use any GL API. It only calculates & stores the values
5979 * in internal storage for further usage.
5981 void GPUShaderFP64Test4::generateUniformValues()
5983 _stage_data* stages[] = { &m_data_cs, &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
5984 const unsigned int n_stages = sizeof(stages) / sizeof(stages[0]);
5986 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
5988 _stage_data* stage_ptr = stages[n_stage];
5990 /* Iterate through all uniform components and assign them double values */
5991 double* double_ptrs[] = {
5992 &stage_ptr->uniform_structure_arrays[0].uniform_double,
5993 stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 0,
5994 stage_ptr->uniform_structure_arrays[0].uniform_double_arr + 1,
5995 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 0,
5996 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 1,
5997 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 2,
5998 stage_ptr->uniform_structure_arrays[0].uniform_dvec2 + 3,
5999 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 0,
6000 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 1,
6001 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 2,
6002 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 3,
6003 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 4,
6004 stage_ptr->uniform_structure_arrays[0].uniform_dvec3 + 5,
6005 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 0,
6006 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 1,
6007 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 2,
6008 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 3,
6009 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 4,
6010 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 5,
6011 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 6,
6012 stage_ptr->uniform_structure_arrays[0].uniform_dvec4 + 7,
6013 &stage_ptr->uniform_structure_arrays[1].uniform_double,
6014 stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 0,
6015 stage_ptr->uniform_structure_arrays[1].uniform_double_arr + 1,
6016 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 0,
6017 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 1,
6018 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 2,
6019 stage_ptr->uniform_structure_arrays[1].uniform_dvec2 + 3,
6020 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 0,
6021 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 1,
6022 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 2,
6023 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 3,
6024 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 4,
6025 stage_ptr->uniform_structure_arrays[1].uniform_dvec3 + 5,
6026 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 0,
6027 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 1,
6028 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 2,
6029 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 3,
6030 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 4,
6031 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 5,
6032 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 6,
6033 stage_ptr->uniform_structure_arrays[1].uniform_dvec4 + 7,
6034 &stage_ptr->uniforms.uniform_double,
6035 stage_ptr->uniforms.uniform_double_arr + 0,
6036 stage_ptr->uniforms.uniform_double_arr + 1,
6037 stage_ptr->uniforms.uniform_dvec2 + 0,
6038 stage_ptr->uniforms.uniform_dvec2 + 1,
6039 stage_ptr->uniforms.uniform_dvec2_arr + 0,
6040 stage_ptr->uniforms.uniform_dvec2_arr + 1,
6041 stage_ptr->uniforms.uniform_dvec2_arr + 2,
6042 stage_ptr->uniforms.uniform_dvec2_arr + 3,
6043 stage_ptr->uniforms.uniform_dvec3 + 0,
6044 stage_ptr->uniforms.uniform_dvec3 + 1,
6045 stage_ptr->uniforms.uniform_dvec3 + 2,
6046 stage_ptr->uniforms.uniform_dvec3_arr + 0,
6047 stage_ptr->uniforms.uniform_dvec3_arr + 1,
6048 stage_ptr->uniforms.uniform_dvec3_arr + 2,
6049 stage_ptr->uniforms.uniform_dvec3_arr + 3,
6050 stage_ptr->uniforms.uniform_dvec3_arr + 4,
6051 stage_ptr->uniforms.uniform_dvec3_arr + 5,
6052 stage_ptr->uniforms.uniform_dvec4 + 0,
6053 stage_ptr->uniforms.uniform_dvec4 + 1,
6054 stage_ptr->uniforms.uniform_dvec4 + 2,
6055 stage_ptr->uniforms.uniform_dvec4 + 3,
6056 stage_ptr->uniforms.uniform_dvec4_arr + 0,
6057 stage_ptr->uniforms.uniform_dvec4_arr + 1,
6058 stage_ptr->uniforms.uniform_dvec4_arr + 2,
6059 stage_ptr->uniforms.uniform_dvec4_arr + 3,
6060 stage_ptr->uniforms.uniform_dvec4_arr + 4,
6061 stage_ptr->uniforms.uniform_dvec4_arr + 5,
6062 stage_ptr->uniforms.uniform_dvec4_arr + 6,
6063 stage_ptr->uniforms.uniform_dvec4_arr + 7,
6065 const unsigned int n_double_ptrs = sizeof(double_ptrs) / sizeof(double_ptrs[0]);
6067 for (unsigned int n_double_ptr = 0; n_double_ptr < n_double_ptrs; ++n_double_ptr)
6069 double* double_ptr = double_ptrs[n_double_ptr];
6071 /* Generate the value. Use magic numbers to generate a set of double-precision
6072 * floating-point numbers.
6074 static int seed = 16762362;
6076 *double_ptr = ((double)(seed % 1732)) / 125.7 * (((seed % 2) == 0) ? 1 : -1);
6079 } /* for (all pointers to double variables) */
6080 } /* for (all stages) */
6083 /** Initializes all program & shader objects required to run the test. The function also
6084 * retrieves locations of all uniforms defined by both program objects.
6086 void GPUShaderFP64Test4::initProgramObjects()
6088 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6090 /* Create program & shader objects */
6092 /* Compute shader support and GL 4.2 required */
6093 if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
6094 (true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
6096 m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
6099 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
6100 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
6101 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
6102 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
6103 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
6104 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
6106 /* m_cs_id is initialized only if compute shaders are supported */
6109 m_po_cs_id = gl.createProgram();
6112 m_po_noncs_id = gl.createProgram();
6113 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
6115 /* Configure compute shader body */
6116 const char* cs_body = "#version 420\n"
6117 "#extension GL_ARB_compute_shader : require\n"
6119 "layout(local_size_x = 2, local_size_y = 2, local_size_z = 2) in;\n"
6121 "layout(rgba32f) uniform image2D testImage;\n"
6123 "uniform double cs_double;\n"
6124 "uniform dvec2 cs_dvec2;\n"
6125 "uniform dvec3 cs_dvec3;\n"
6126 "uniform dvec4 cs_dvec4;\n"
6127 "uniform double cs_double_arr[2];\n"
6128 "uniform dvec2 cs_dvec2_arr [2];\n"
6129 "uniform dvec3 cs_dvec3_arr [2];\n"
6130 "uniform dvec4 cs_dvec4_arr [2];\n"
6132 "uniform struct cs_struct\n"
6134 " double struct_double;\n"
6135 " dvec2 struct_dvec2;\n"
6136 " dvec3 struct_dvec3;\n"
6137 " dvec4 struct_dvec4;\n"
6142 " double tmp = cs_double * cs_dvec2.x * cs_dvec3.y "
6144 " cs_double_arr[0] * cs_dvec2_arr[0].x * "
6145 "cs_dvec3_arr[0].z * cs_dvec4_arr[0].w *\n"
6146 " cs_double_arr[1] * cs_dvec2_arr[1].x * "
6147 "cs_dvec3_arr[1].z * cs_dvec4_arr[1].w *\n"
6148 " cs_array[0].struct_double * cs_array[0].struct_dvec2.y * "
6149 "cs_array[0].struct_dvec3.z * cs_array[0].struct_dvec4.w *\n"
6150 " cs_array[1].struct_double * cs_array[1].struct_dvec2.y * "
6151 "cs_array[1].struct_dvec3.z * cs_array[1].struct_dvec4.w;\n"
6153 " imageStore(testImage, ivec2(0, 0), (tmp > 1.0) ? vec4(1.0) : vec4(0.0) );\n"
6156 /* m_cs_id is initialized only if compute shaders are supported */
6159 gl.shaderSource(m_cs_id, 1 /* count */, &cs_body, DE_NULL /* length */);
6160 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
6163 /* Configure vertex shader body */
6164 const char* vs_body = "#version 400\n"
6166 "uniform double vs_double;\n"
6167 "uniform dvec2 vs_dvec2;\n"
6168 "uniform dvec3 vs_dvec3;\n"
6169 "uniform dvec4 vs_dvec4;\n"
6170 "uniform double vs_double_arr[2];\n"
6171 "uniform dvec2 vs_dvec2_arr [2];\n"
6172 "uniform dvec3 vs_dvec3_arr [2];\n"
6173 "uniform dvec4 vs_dvec4_arr [2];\n"
6175 "uniform struct vs_struct\n"
6177 " double struct_double;\n"
6178 " dvec2 struct_dvec2;\n"
6179 " dvec3 struct_dvec3;\n"
6180 " dvec4 struct_dvec4;\n"
6185 " if (vs_double * vs_dvec2.x * vs_dvec3.x "
6187 " vs_double_arr[0] * vs_dvec2_arr[0].x * vs_dvec3_arr[0].x "
6188 "* vs_dvec4_arr[0].x *\n"
6189 " vs_double_arr[1] * vs_dvec2_arr[1].x * vs_dvec3_arr[1].x "
6190 "* vs_dvec4_arr[1].x *\n"
6191 " vs_array[0].struct_double * vs_array[0].struct_dvec2.x * vs_array[0].struct_dvec3.x "
6192 "* vs_array[0].struct_dvec4.x *\n"
6193 " vs_array[1].struct_double * vs_array[1].struct_dvec2.x * vs_array[1].struct_dvec3.x "
6194 "* vs_array[1].struct_dvec4.x > 1.0)\n"
6196 " gl_Position = vec4(0);\n"
6200 " gl_Position = vec4(1);\n"
6204 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
6205 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
6207 /* Configure tessellation control shader body */
6208 const char* tc_body = "#version 400\n"
6210 "uniform double tc_double;\n"
6211 "uniform dvec2 tc_dvec2;\n"
6212 "uniform dvec3 tc_dvec3;\n"
6213 "uniform dvec4 tc_dvec4;\n"
6214 "uniform double tc_double_arr[2];\n"
6215 "uniform dvec2 tc_dvec2_arr [2];\n"
6216 "uniform dvec3 tc_dvec3_arr [2];\n"
6217 "uniform dvec4 tc_dvec4_arr [2];\n"
6219 "uniform struct tc_struct\n"
6221 " double struct_double;\n"
6222 " dvec2 struct_dvec2;\n"
6223 " dvec3 struct_dvec3;\n"
6224 " dvec4 struct_dvec4;\n"
6227 "layout(vertices = 4) out;\n"
6231 " gl_TessLevelOuter[0] = (tc_double > 1.0) ? 2.0 : 3.0;\n"
6232 " gl_TessLevelOuter[1] = (tc_dvec2.x > 1.0) ? 3.0 : 4.0;\n"
6233 " gl_TessLevelOuter[2] = (tc_dvec3.x > 1.0) ? 4.0 : 5.0;\n"
6234 " gl_TessLevelOuter[3] = (tc_dvec4.x > 1.0) ? 5.0 : 6.0;\n"
6235 " gl_TessLevelInner[0] = (tc_double_arr[0] > 1.0) ? 6.0 : 7.0;\n"
6236 " gl_TessLevelInner[1] = (tc_double_arr[1] > 1.0) ? 7.0 : 8.0;\n"
6238 " if (tc_dvec2_arr[0].y * tc_dvec2_arr[1].y *\n"
6239 " tc_dvec3_arr[0].z * tc_dvec3_arr[1].z *\n"
6240 " tc_dvec4_arr[0].z * tc_dvec4_arr[1].z *\n"
6241 " tc_array[0].struct_double * tc_array[0].struct_dvec2.x * \n"
6242 " tc_array[0].struct_dvec3.y * tc_array[0].struct_dvec4.z * \n"
6243 " tc_array[1].struct_double * tc_array[1].struct_dvec2.x * \n"
6244 " tc_array[1].struct_dvec3.y * tc_array[1].struct_dvec4.z > 0.0)\n"
6246 " gl_TessLevelInner[1] = 3.0;\n"
6250 gl.shaderSource(m_tc_id, 1 /* count */, &tc_body, DE_NULL /* length */);
6251 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
6253 /* Configure tessellation evaluation shader body */
6254 const char* te_body = "#version 400\n"
6256 "uniform double te_double;\n"
6257 "uniform dvec2 te_dvec2;\n"
6258 "uniform dvec3 te_dvec3;\n"
6259 "uniform dvec4 te_dvec4;\n"
6260 "uniform double te_double_arr[2];\n"
6261 "uniform dvec2 te_dvec2_arr [2];\n"
6262 "uniform dvec3 te_dvec3_arr [2];\n"
6263 "uniform dvec4 te_dvec4_arr [2];\n"
6265 "uniform struct te_struct\n"
6267 " double struct_double;\n"
6268 " dvec2 struct_dvec2;\n"
6269 " dvec3 struct_dvec3;\n"
6270 " dvec4 struct_dvec4;\n"
6273 "layout(triangles) in;\n"
6277 " if (te_double * te_dvec2.x * te_dvec3.x "
6279 " te_double_arr[0] * te_dvec2_arr[0].x * te_dvec3_arr[0].x "
6280 "* te_dvec4_arr[0].x *\n"
6281 " te_double_arr[1] * te_dvec2_arr[1].x * te_dvec3_arr[1].x "
6282 "* te_dvec4_arr[1].x *\n"
6283 " te_array[0].struct_double * te_array[0].struct_dvec2.x * te_array[0].struct_dvec3.x "
6284 "* te_array[0].struct_dvec4.x *\n"
6285 " te_array[1].struct_double * te_array[1].struct_dvec2.x * te_array[1].struct_dvec3.x "
6286 "* te_array[1].struct_dvec4.x > 1.0)\n"
6288 " gl_Position = gl_in[0].gl_Position;\n"
6292 " gl_Position = gl_in[0].gl_Position + vec4(1);\n"
6296 gl.shaderSource(m_te_id, 1 /* count */, &te_body, DE_NULL /* length */);
6297 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
6299 /* Configure geometry shader body */
6300 const char* gs_body = "#version 400\n"
6302 "uniform double gs_double;\n"
6303 "uniform dvec2 gs_dvec2;\n"
6304 "uniform dvec3 gs_dvec3;\n"
6305 "uniform dvec4 gs_dvec4;\n"
6306 "uniform double gs_double_arr[2];\n"
6307 "uniform dvec2 gs_dvec2_arr [2];\n"
6308 "uniform dvec3 gs_dvec3_arr [2];\n"
6309 "uniform dvec4 gs_dvec4_arr [2];\n"
6311 "uniform struct gs_struct\n"
6313 " double struct_double;\n"
6314 " dvec2 struct_dvec2;\n"
6315 " dvec3 struct_dvec3;\n"
6316 " dvec4 struct_dvec4;\n"
6319 "layout (points) in;\n"
6320 "layout (points, max_vertices = 1) out;\n"
6324 " if (gs_double * gs_dvec2.x * gs_dvec3.x "
6326 " gs_double_arr[0] * gs_dvec2_arr[0].x * gs_dvec3_arr[0].x "
6327 "* gs_dvec4_arr[0].x *\n"
6328 " gs_double_arr[1] * gs_dvec2_arr[1].x * gs_dvec3_arr[1].x "
6329 "* gs_dvec4_arr[1].x *\n"
6330 " gs_array[0].struct_double * gs_array[0].struct_dvec2.x * gs_array[0].struct_dvec3.x "
6331 "* gs_array[0].struct_dvec4.x *\n"
6332 " gs_array[1].struct_double * gs_array[1].struct_dvec2.x * gs_array[1].struct_dvec3.x "
6333 "* gs_array[1].struct_dvec4.x > 1.0)\n"
6335 " gl_Position = gl_in[0].gl_Position;\n"
6339 " gl_Position = gl_in[0].gl_Position + vec4(1);\n"
6345 gl.shaderSource(m_gs_id, 1 /* count */, &gs_body, DE_NULL /* length */);
6346 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
6348 /* Configure fragment shader body */
6349 const char* fs_body = "#version 400\n"
6351 "uniform double fs_double;\n"
6352 "uniform dvec2 fs_dvec2;\n"
6353 "uniform dvec3 fs_dvec3;\n"
6354 "uniform dvec4 fs_dvec4;\n"
6355 "uniform double fs_double_arr[2];\n"
6356 "uniform dvec2 fs_dvec2_arr [2];\n"
6357 "uniform dvec3 fs_dvec3_arr [2];\n"
6358 "uniform dvec4 fs_dvec4_arr [2];\n"
6360 "uniform struct fs_struct\n"
6362 " double struct_double;\n"
6363 " dvec2 struct_dvec2;\n"
6364 " dvec3 struct_dvec3;\n"
6365 " dvec4 struct_dvec4;\n"
6368 "out vec4 result;\n"
6372 " if (fs_double * fs_dvec2.x * fs_dvec3.x "
6374 " fs_double_arr[0] * fs_dvec2_arr[0].x * fs_dvec3_arr[0].x "
6375 "* fs_dvec4_arr[0].x *\n"
6376 " fs_double_arr[1] * fs_dvec2_arr[1].x * fs_dvec3_arr[1].x "
6377 "* fs_dvec4_arr[1].x *\n"
6378 " fs_array[0].struct_double * fs_array[0].struct_dvec2.x * fs_array[0].struct_dvec3.x "
6379 "* fs_array[0].struct_dvec4.x *\n"
6380 " fs_array[1].struct_double * fs_array[1].struct_dvec2.x * fs_array[1].struct_dvec3.x "
6381 "* fs_array[1].struct_dvec4.x > 1.0)\n"
6383 " result = vec4(0.0);\n"
6387 " result = vec4(1.0);\n"
6391 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body, DE_NULL /* length */);
6392 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
6394 /* Compile the shaders */
6395 const glw::GLuint shaders[] = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
6396 const unsigned int n_shaders = sizeof(shaders) / sizeof(shaders[0]);
6398 for (unsigned int n_shader = 0; n_shader < n_shaders; ++n_shader)
6400 glw::GLint compile_status = GL_FALSE;
6401 glw::GLuint so_id = shaders[n_shader];
6403 /* Skip compute shader if not supported */
6409 gl.compileShader(so_id);
6410 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed");
6412 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
6413 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed");
6415 if (compile_status != GL_TRUE)
6417 TCU_FAIL("Shader compilation failed");
6420 if (so_id == m_cs_id)
6422 gl.attachShader(m_po_cs_id, so_id);
6426 gl.attachShader(m_po_noncs_id, so_id);
6429 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
6430 } /* for (all shaders) */
6432 /* Link the program */
6433 const glw::GLuint programs[] = { m_po_cs_id, m_po_noncs_id };
6434 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);
6435 glw::GLint link_status = GL_FALSE;
6437 for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
6439 glw::GLuint po_id = programs[n_program];
6441 /* Skip compute shader program if not supported */
6447 gl.linkProgram(po_id);
6448 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
6450 gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
6451 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
6453 if (link_status != GL_TRUE)
6455 TCU_FAIL("Program linking failed");
6457 } /* for (both program objects) */
6459 /* Retrieve uniform locations */
6460 _stage_data* cs_stage_data[] = { &m_data_cs };
6461 static const char* cs_uniform_prefixes[] = { "cs_" };
6462 static const unsigned int n_cs_uniform_prefixes = sizeof(cs_uniform_prefixes) / sizeof(cs_uniform_prefixes[0]);
6464 _stage_data* noncs_stage_data[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
6465 static const char* noncs_uniform_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" };
6466 static const unsigned int n_noncs_uniform_prefixes =
6467 sizeof(noncs_uniform_prefixes) / sizeof(noncs_uniform_prefixes[0]);
6469 for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
6471 unsigned int n_uniform_prefixes = DE_NULL;
6472 glw::GLuint po_id = programs[n_program];
6473 _stage_data** stages_data = DE_NULL;
6474 const char** uniform_prefixes = DE_NULL;
6478 stages_data = cs_stage_data;
6479 uniform_prefixes = cs_uniform_prefixes;
6480 n_uniform_prefixes = n_cs_uniform_prefixes;
6484 stages_data = noncs_stage_data;
6485 uniform_prefixes = noncs_uniform_prefixes;
6486 n_uniform_prefixes = n_noncs_uniform_prefixes;
6489 /* Skip compute shader program if not supported */
6495 /* Uniform names used by the test program consist of a prefix (different for each
6496 * shader stage) and a common part.
6498 for (unsigned int n_uniform_prefix = 0; n_uniform_prefix < n_uniform_prefixes; ++n_uniform_prefix)
6500 _stage_data* stage_data = stages_data[n_uniform_prefix];
6501 std::string uniform_prefix = std::string(uniform_prefixes[n_uniform_prefix]);
6502 std::string uniform_double_name = uniform_prefix + "double";
6503 std::string uniform_double_arr0_name = uniform_prefix + "double_arr[0]";
6504 std::string uniform_double_arr1_name = uniform_prefix + "double_arr[1]";
6505 std::string uniform_dvec2_name = uniform_prefix + "dvec2";
6506 std::string uniform_dvec2_arr0_name = uniform_prefix + "dvec2_arr[0]";
6507 std::string uniform_dvec2_arr1_name = uniform_prefix + "dvec2_arr[1]";
6508 std::string uniform_dvec3_name = uniform_prefix + "dvec3";
6509 std::string uniform_dvec3_arr0_name = uniform_prefix + "dvec3_arr[0]";
6510 std::string uniform_dvec3_arr1_name = uniform_prefix + "dvec3_arr[1]";
6511 std::string uniform_dvec4_name = uniform_prefix + "dvec4";
6512 std::string uniform_dvec4_arr0_name = uniform_prefix + "dvec4_arr[0]";
6513 std::string uniform_dvec4_arr1_name = uniform_prefix + "dvec4_arr[1]";
6514 std::string uniform_arr0_double_name = uniform_prefix + "array[0].struct_double";
6515 std::string uniform_arr0_dvec2_name = uniform_prefix + "array[0].struct_dvec2";
6516 std::string uniform_arr0_dvec3_name = uniform_prefix + "array[0].struct_dvec3";
6517 std::string uniform_arr0_dvec4_name = uniform_prefix + "array[0].struct_dvec4";
6518 std::string uniform_arr1_double_name = uniform_prefix + "array[1].struct_double";
6519 std::string uniform_arr1_dvec2_name = uniform_prefix + "array[1].struct_dvec2";
6520 std::string uniform_arr1_dvec3_name = uniform_prefix + "array[1].struct_dvec3";
6521 std::string uniform_arr1_dvec4_name = uniform_prefix + "array[1].struct_dvec4";
6523 /* Retrieve uniform locations */
6524 stage_data->uniforms.uniform_location_double = gl.getUniformLocation(po_id, uniform_double_name.c_str());
6525 stage_data->uniforms.uniform_location_double_arr[0] =
6526 gl.getUniformLocation(po_id, uniform_double_arr0_name.c_str());
6527 stage_data->uniforms.uniform_location_double_arr[1] =
6528 gl.getUniformLocation(po_id, uniform_double_arr1_name.c_str());
6529 stage_data->uniforms.uniform_location_dvec2 = gl.getUniformLocation(po_id, uniform_dvec2_name.c_str());
6530 stage_data->uniforms.uniform_location_dvec2_arr[0] =
6531 gl.getUniformLocation(po_id, uniform_dvec2_arr0_name.c_str());
6532 stage_data->uniforms.uniform_location_dvec2_arr[1] =
6533 gl.getUniformLocation(po_id, uniform_dvec2_arr1_name.c_str());
6534 stage_data->uniforms.uniform_location_dvec3 = gl.getUniformLocation(po_id, uniform_dvec3_name.c_str());
6535 stage_data->uniforms.uniform_location_dvec3_arr[0] =
6536 gl.getUniformLocation(po_id, uniform_dvec3_arr0_name.c_str());
6537 stage_data->uniforms.uniform_location_dvec3_arr[1] =
6538 gl.getUniformLocation(po_id, uniform_dvec3_arr1_name.c_str());
6539 stage_data->uniforms.uniform_location_dvec4 = gl.getUniformLocation(po_id, uniform_dvec4_name.c_str());
6540 stage_data->uniforms.uniform_location_dvec4_arr[0] =
6541 gl.getUniformLocation(po_id, uniform_dvec4_arr0_name.c_str());
6542 stage_data->uniforms.uniform_location_dvec4_arr[1] =
6543 gl.getUniformLocation(po_id, uniform_dvec4_arr1_name.c_str());
6544 stage_data->uniform_structure_arrays[0].uniform_location_double =
6545 gl.getUniformLocation(po_id, uniform_arr0_double_name.c_str());
6546 stage_data->uniform_structure_arrays[0].uniform_location_dvec2 =
6547 gl.getUniformLocation(po_id, uniform_arr0_dvec2_name.c_str());
6548 stage_data->uniform_structure_arrays[0].uniform_location_dvec3 =
6549 gl.getUniformLocation(po_id, uniform_arr0_dvec3_name.c_str());
6550 stage_data->uniform_structure_arrays[0].uniform_location_dvec4 =
6551 gl.getUniformLocation(po_id, uniform_arr0_dvec4_name.c_str());
6552 stage_data->uniform_structure_arrays[1].uniform_location_double =
6553 gl.getUniformLocation(po_id, uniform_arr1_double_name.c_str());
6554 stage_data->uniform_structure_arrays[1].uniform_location_dvec2 =
6555 gl.getUniformLocation(po_id, uniform_arr1_dvec2_name.c_str());
6556 stage_data->uniform_structure_arrays[1].uniform_location_dvec3 =
6557 gl.getUniformLocation(po_id, uniform_arr1_dvec3_name.c_str());
6558 stage_data->uniform_structure_arrays[1].uniform_location_dvec4 =
6559 gl.getUniformLocation(po_id, uniform_arr1_dvec4_name.c_str());
6560 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed.");
6562 if (stage_data->uniforms.uniform_location_double == -1 ||
6563 stage_data->uniforms.uniform_location_double_arr[0] == -1 ||
6564 stage_data->uniforms.uniform_location_double_arr[1] == -1 ||
6565 stage_data->uniforms.uniform_location_dvec2 == -1 ||
6566 stage_data->uniforms.uniform_location_dvec2_arr[0] == -1 ||
6567 stage_data->uniforms.uniform_location_dvec2_arr[1] == -1 ||
6568 stage_data->uniforms.uniform_location_dvec3 == -1 ||
6569 stage_data->uniforms.uniform_location_dvec3_arr[0] == -1 ||
6570 stage_data->uniforms.uniform_location_dvec3_arr[1] == -1 ||
6571 stage_data->uniforms.uniform_location_dvec4 == -1 ||
6572 stage_data->uniforms.uniform_location_dvec4_arr[0] == -1 ||
6573 stage_data->uniforms.uniform_location_dvec4_arr[1] == -1 ||
6574 stage_data->uniform_structure_arrays[0].uniform_location_double == -1 ||
6575 stage_data->uniform_structure_arrays[0].uniform_location_dvec2 == -1 ||
6576 stage_data->uniform_structure_arrays[0].uniform_location_dvec3 == -1 ||
6577 stage_data->uniform_structure_arrays[0].uniform_location_dvec4 == -1 ||
6578 stage_data->uniform_structure_arrays[1].uniform_location_double == -1 ||
6579 stage_data->uniform_structure_arrays[1].uniform_location_dvec2 == -1 ||
6580 stage_data->uniform_structure_arrays[1].uniform_location_dvec3 == -1 ||
6581 stage_data->uniform_structure_arrays[1].uniform_location_dvec4 == -1)
6583 TCU_FAIL("At least one uniform is considered inactive which is invalid.");
6586 /* Make sure locations of subsequent items in array uniforms are correct */
6587 if (stage_data->uniforms.uniform_location_double_arr[1] !=
6588 (stage_data->uniforms.uniform_location_double_arr[0] + 1) ||
6589 stage_data->uniforms.uniform_location_dvec2_arr[1] !=
6590 (stage_data->uniforms.uniform_location_dvec2_arr[0] + 1) ||
6591 stage_data->uniforms.uniform_location_dvec3_arr[1] !=
6592 (stage_data->uniforms.uniform_location_dvec3_arr[0] + 1) ||
6593 stage_data->uniforms.uniform_location_dvec4_arr[1] !=
6594 (stage_data->uniforms.uniform_location_dvec4_arr[0] + 1))
6596 m_testCtx.getLog() << tcu::TestLog::Message << "Uniform locations:"
6598 << stage_data->uniforms.uniform_location_double_arr[0]
6599 << " double_arr[1]:" << stage_data->uniforms.uniform_location_double_arr[1]
6600 << " dvec2_arr[0]:" << stage_data->uniforms.uniform_location_dvec2_arr[0]
6601 << " dvec2_arr[1]:" << stage_data->uniforms.uniform_location_dvec2_arr[1]
6602 << " dvec3_arr[0]:" << stage_data->uniforms.uniform_location_dvec3_arr[0]
6603 << " dvec3_arr[1]:" << stage_data->uniforms.uniform_location_dvec3_arr[1]
6604 << " dvec4_arr[0]:" << stage_data->uniforms.uniform_location_dvec4_arr[0]
6605 << " dvec4_arr[1]:" << stage_data->uniforms.uniform_location_dvec4_arr[1]
6606 << tcu::TestLog::EndMessage;
6608 TCU_FAIL("Double-precision uniform array item locations are invalid.");
6610 } /* for (all uniform prefixes) */
6611 } /* for (both program objects) */
6614 /** Initializes all objects required to run the test. */
6615 void GPUShaderFP64Test4::initTest()
6617 initProgramObjects();
6619 generateUniformValues();
6620 initUniformValues();
6623 /** Assigns values generated by generateUniformValues() to uniforms defined by
6624 * both program objects.
6626 void GPUShaderFP64Test4::initUniformValues()
6628 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6630 /* Iterate through all programs */
6631 _stage_data* cs_stages[] = { &m_data_cs };
6632 _stage_data* noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
6633 const unsigned int n_cs_stages = sizeof(cs_stages) / sizeof(cs_stages[0]);
6634 const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]);
6636 const glw::GLuint programs[] = { m_po_cs_id, m_po_noncs_id };
6637 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);
6639 for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
6641 glw::GLuint po_id = programs[n_program];
6642 unsigned int n_stages = 0;
6643 _stage_data** stage_data = DE_NULL;
6645 if (po_id == m_po_cs_id)
6647 n_stages = n_cs_stages;
6648 stage_data = cs_stages;
6652 n_stages = n_noncs_stages;
6653 stage_data = noncs_stages;
6656 /* Skip compute shader program if not supported */
6662 gl.useProgram(po_id);
6663 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
6665 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
6667 /* Iterate through all uniforms */
6668 _stage_data* stage_ptr = stage_data[n_stage];
6670 gl.uniform1d(stage_ptr->uniforms.uniform_location_double, stage_ptr->uniforms.uniform_double);
6671 gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[0], stage_ptr->uniforms.uniform_double_arr[0]);
6672 gl.uniform1d(stage_ptr->uniforms.uniform_location_double_arr[1], stage_ptr->uniforms.uniform_double_arr[1]);
6673 gl.uniform1d(stage_ptr->uniform_structure_arrays[0].uniform_location_double,
6674 stage_ptr->uniform_structure_arrays[0].uniform_double);
6675 gl.uniform1d(stage_ptr->uniform_structure_arrays[1].uniform_location_double,
6676 stage_ptr->uniform_structure_arrays[1].uniform_double);
6677 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform1d() call(s) failed.");
6679 gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2, 1 /* count */, stage_ptr->uniforms.uniform_dvec2);
6680 gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[0], 1 /* count */,
6681 stage_ptr->uniforms.uniform_dvec2_arr + 0);
6682 gl.uniform2dv(stage_ptr->uniforms.uniform_location_dvec2_arr[1], 1 /* count */,
6683 stage_ptr->uniforms.uniform_dvec2_arr + 2);
6684 gl.uniform2dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2, 1 /* count */,
6685 stage_ptr->uniform_structure_arrays[0].uniform_dvec2);
6686 gl.uniform2dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2, 1 /* count */,
6687 stage_ptr->uniform_structure_arrays[1].uniform_dvec2);
6688 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform2dv() call(s) failed.");
6690 gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3, 1 /* count */, stage_ptr->uniforms.uniform_dvec3);
6691 gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[0], 1 /* count */,
6692 stage_ptr->uniforms.uniform_dvec3_arr + 0);
6693 gl.uniform3dv(stage_ptr->uniforms.uniform_location_dvec3_arr[1], 1 /* count */,
6694 stage_ptr->uniforms.uniform_dvec3_arr + 3);
6695 gl.uniform3dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3, 1 /* count */,
6696 stage_ptr->uniform_structure_arrays[0].uniform_dvec3);
6697 gl.uniform3dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3, 1 /* count */,
6698 stage_ptr->uniform_structure_arrays[1].uniform_dvec3);
6699 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform3dv() call(s) failed.");
6701 gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4, 1 /* count */, stage_ptr->uniforms.uniform_dvec4);
6702 gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[0], 1 /* count */,
6703 stage_ptr->uniforms.uniform_dvec4_arr + 0);
6704 gl.uniform4dv(stage_ptr->uniforms.uniform_location_dvec4_arr[1], 1 /* count */,
6705 stage_ptr->uniforms.uniform_dvec4_arr + 4);
6706 gl.uniform4dv(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4, 1 /* count */,
6707 stage_ptr->uniform_structure_arrays[0].uniform_dvec4);
6708 gl.uniform4dv(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4, 1 /* count */,
6709 stage_ptr->uniform_structure_arrays[1].uniform_dvec4);
6710 GLU_EXPECT_NO_ERROR(gl.getError(), "gluniform4dv() call(s) failed.");
6711 } /* for (all shader stages) */
6712 } /* for (both program objects) */
6715 /** Executes test iteration.
6717 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
6719 tcu::TestNode::IterateResult GPUShaderFP64Test4::iterate()
6721 /* This test does not verify GL_ARB_gpu_shader_fp64 support on purpose */
6723 /* Initialize all objects required to run the test */
6726 /* Verify the implementation reports correct values for all stages we've configured */
6727 m_has_test_passed &= verifyUniformValues();
6729 /* Is this also the case when "program interface query" mechanism is used? */
6730 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_program_interface_query"))
6732 m_has_test_passed &= verifyProgramInterfaceQuerySupport();
6736 if (m_has_test_passed)
6738 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6742 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6750 * a) glGetProgramResourceIndex()
6751 * b) glGetProgramResourceiv()
6752 * c) glGetProgramResourceName()
6754 * functions return correct values for double-precision uniforms.
6756 * @return true if the verification was passed, false otherwise.
6758 bool GPUShaderFP64Test4::verifyProgramInterfaceQuerySupport()
6760 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6763 /* Iterate through all programs */
6764 const char* cs_prefixes[] = { "cs_" };
6765 _stage_data* cs_stages[] = { &m_data_cs };
6766 const char* noncs_prefixes[] = { "fs_", "gs_", "tc_", "te_", "vs_" };
6767 _stage_data* noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
6768 const unsigned int n_cs_stages = sizeof(cs_stages) / sizeof(cs_stages[0]);
6769 const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]);
6771 const glw::GLuint programs[] = { m_po_cs_id, m_po_noncs_id };
6772 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);
6774 for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
6776 glw::GLuint po_id = programs[n_program];
6777 unsigned int n_stages = 0;
6778 const char** stage_prefixes = DE_NULL;
6779 _stage_data** stage_data = DE_NULL;
6781 if (po_id == m_po_cs_id)
6783 n_stages = n_cs_stages;
6784 stage_data = cs_stages;
6785 stage_prefixes = cs_prefixes;
6789 n_stages = n_noncs_stages;
6790 stage_data = noncs_stages;
6791 stage_prefixes = noncs_prefixes;
6794 /* Skip compute shader program if not supported */
6800 /* Determine maximum uniform name length */
6801 glw::GLint max_uniform_name_length = 0;
6803 gl.getProgramInterfaceiv(po_id, GL_UNIFORM, GL_MAX_NAME_LENGTH, &max_uniform_name_length);
6804 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInterfaceiv() call failed.");
6806 /* Allocate a buffer we will use to hold uniform names */
6807 m_uniform_name_buffer = new char[max_uniform_name_length];
6809 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
6811 /* Iterate through all uniforms */
6812 _stage_data* stage_ptr = stage_data[n_stage];
6813 const char* stage_prefix = stage_prefixes[n_stage];
6815 /* Construct an array that will be used to run the test in an automated manner */
6816 _program_interface_query_test_item uniforms[] = {
6817 /* array size */ /* name */ /* type */ /* location */
6818 { 1, "double", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double },
6819 { 2, "double_arr[0]", GL_DOUBLE, stage_ptr->uniforms.uniform_location_double_arr[0] },
6820 { 1, "dvec2", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2 },
6821 { 2, "dvec2_arr[0]", GL_DOUBLE_VEC2, stage_ptr->uniforms.uniform_location_dvec2_arr[0] },
6822 { 1, "dvec3", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3 },
6823 { 2, "dvec3_arr[0]", GL_DOUBLE_VEC3, stage_ptr->uniforms.uniform_location_dvec3_arr[0] },
6824 { 1, "dvec4", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4 },
6825 { 2, "dvec4_arr[0]", GL_DOUBLE_VEC4, stage_ptr->uniforms.uniform_location_dvec4_arr[0] },
6826 { 1, "array[0].struct_double", GL_DOUBLE,
6827 stage_ptr->uniform_structure_arrays->uniform_location_double },
6828 { 1, "array[0].struct_dvec2", GL_DOUBLE_VEC2,
6829 stage_ptr->uniform_structure_arrays->uniform_location_dvec2 },
6830 { 1, "array[0].struct_dvec3", GL_DOUBLE_VEC3,
6831 stage_ptr->uniform_structure_arrays->uniform_location_dvec3 },
6832 { 1, "array[0].struct_dvec4", GL_DOUBLE_VEC4,
6833 stage_ptr->uniform_structure_arrays->uniform_location_dvec4 },
6834 { 1, "array[1].struct_double", GL_DOUBLE,
6835 stage_ptr->uniform_structure_arrays->uniform_location_double },
6836 { 1, "array[1].struct_dvec2", GL_DOUBLE_VEC2,
6837 stage_ptr->uniform_structure_arrays->uniform_location_dvec2 },
6838 { 1, "array[1].struct_dvec3", GL_DOUBLE_VEC3,
6839 stage_ptr->uniform_structure_arrays->uniform_location_dvec3 },
6840 { 1, "array[1].struct_dvec4", GL_DOUBLE_VEC4,
6841 stage_ptr->uniform_structure_arrays->uniform_location_dvec4 },
6843 const unsigned int n_uniforms = sizeof(uniforms) / sizeof(uniforms[0]);
6845 /* Prefix the names with stage-specific string */
6846 for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
6848 _program_interface_query_test_item& current_item = uniforms[n_uniform];
6850 current_item.name = std::string(stage_prefix) + current_item.name;
6851 } /* for (all uniform descriptors) */
6853 const glw::GLenum properties[] = { GL_ARRAY_SIZE, GL_TYPE };
6854 const unsigned int n_properties = sizeof(properties) / sizeof(properties[0]);
6856 for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
6858 _program_interface_query_test_item& current_item = uniforms[n_uniform];
6859 glw::GLint n_written_items = 0;
6860 glw::GLint retrieved_array_size = 0;
6861 glw::GLint retrieved_name_length = 0;
6862 glw::GLenum retrieved_type = GL_NONE;
6863 glw::GLint temp_buffer[2] = { 0, GL_NONE };
6865 /* Retrieve index of the iteration-specific uniform */
6866 glw::GLuint resource_index = gl.getProgramResourceIndex(po_id, GL_UNIFORM, current_item.name.c_str());
6867 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex() call failed.");
6869 /* Make sure glGetProgramResourceName() returns correct values */
6870 memset(m_uniform_name_buffer, 0, max_uniform_name_length);
6872 gl.getProgramResourceName(po_id, GL_UNIFORM, /* interface */
6873 resource_index, max_uniform_name_length, &retrieved_name_length,
6874 m_uniform_name_buffer);
6875 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName() call failed.");
6877 if (current_item.name.length() != (glw::GLuint)retrieved_name_length ||
6878 memcmp(m_uniform_name_buffer, current_item.name.c_str(), retrieved_name_length) != 0)
6880 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid uniform name was reported at index ["
6881 << resource_index << "]"
6883 << current_item.name << "]"
6885 << m_uniform_name_buffer << "]" << tcu::TestLog::EndMessage;
6891 /* Make sure glGetProgramResourceiv() returns correct values for GL_TYPE and GL_ARRAY_SIZE queries */
6892 gl.getProgramResourceiv(po_id, GL_UNIFORM, /* interface */
6893 resource_index, n_properties, properties,
6894 sizeof(temp_buffer) / sizeof(temp_buffer[0]), &n_written_items, temp_buffer);
6895 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv() call failed.");
6897 if (n_written_items != n_properties)
6899 TCU_FAIL("Invalid amount of items were reported by glGetProgramResourceiv() call.");
6902 /* For clarity, copy the retrieved values to separate variables */
6903 retrieved_array_size = temp_buffer[0];
6904 retrieved_type = temp_buffer[1];
6906 /* Verify the values */
6907 if (retrieved_array_size != current_item.expected_array_size)
6909 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid array size reported for uniform ["
6910 << current_item.name << "]"
6911 << ": expected:[" << current_item.expected_array_size << "]"
6913 << retrieved_array_size << "]" << tcu::TestLog::EndMessage;
6918 if (retrieved_type != current_item.expected_type)
6920 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid type reported for uniform ["
6921 << current_item.name << "]"
6922 << ": expected:[" << current_item.expected_type << "]"
6924 << retrieved_type << "]" << tcu::TestLog::EndMessage;
6928 } /* for (all uniforms) */
6929 } /* for (all shader stages) */
6931 /* We're now OK to release the buffer we used to hold uniform names for
6933 if (m_uniform_name_buffer != DE_NULL)
6935 delete[] m_uniform_name_buffer;
6937 m_uniform_name_buffer = DE_NULL;
6939 } /* for (both program objects) */
6944 /** Verifies glGetUniform*() calls return correct values assigned to
6945 * double-precision uniforms.
6947 * @return true if all values reported by OpenGL were found to be correct,
6950 bool GPUShaderFP64Test4::verifyUniformValues()
6952 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6955 /* Iterate through all programs */
6956 _stage_data* cs_stages[] = { &m_data_cs };
6957 _stage_data* noncs_stages[] = { &m_data_fs, &m_data_gs, &m_data_tc, &m_data_te, &m_data_vs };
6958 const unsigned int n_cs_stages = sizeof(cs_stages) / sizeof(cs_stages[0]);
6959 const unsigned int n_noncs_stages = sizeof(noncs_stages) / sizeof(noncs_stages[0]);
6961 const glw::GLuint programs[] = {
6962 m_po_noncs_id, m_po_cs_id,
6964 const unsigned int n_programs = sizeof(programs) / sizeof(programs[0]);
6966 /* Set up rounding for the tests */
6967 deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN);
6969 for (unsigned int n_program = 0; n_program < n_programs; ++n_program)
6971 glw::GLuint po_id = programs[n_program];
6972 unsigned int n_stages = 0;
6973 _stage_data** stage_data = DE_NULL;
6975 if (po_id == m_po_cs_id)
6977 n_stages = n_cs_stages;
6978 stage_data = cs_stages;
6982 n_stages = n_noncs_stages;
6983 stage_data = noncs_stages;
6986 /* Skip compute shader program if not supported */
6992 for (unsigned int n_stage = 0; n_stage < n_stages; ++n_stage)
6994 /* Iterate through all uniforms */
6995 _stage_data* stage_ptr = stage_data[n_stage];
6997 /* Set up arrays that we will guide the automated testing */
6998 const uniform_value_pair double_uniforms[] = {
6999 uniform_value_pair(stage_ptr->uniforms.uniform_location_double, &stage_ptr->uniforms.uniform_double),
7000 uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[0],
7001 stage_ptr->uniforms.uniform_double_arr + 0),
7002 uniform_value_pair(stage_ptr->uniforms.uniform_location_double_arr[1],
7003 stage_ptr->uniforms.uniform_double_arr + 1),
7004 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_double,
7005 &stage_ptr->uniform_structure_arrays[0].uniform_double),
7006 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_double,
7007 &stage_ptr->uniform_structure_arrays[1].uniform_double)
7009 const uniform_value_pair dvec2_uniforms[] = {
7010 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2, stage_ptr->uniforms.uniform_dvec2),
7011 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[0],
7012 stage_ptr->uniforms.uniform_dvec2_arr + 0),
7013 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec2_arr[1],
7014 stage_ptr->uniforms.uniform_dvec2_arr + 2),
7015 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec2,
7016 stage_ptr->uniform_structure_arrays[0].uniform_dvec2),
7017 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec2,
7018 stage_ptr->uniform_structure_arrays[1].uniform_dvec2)
7020 const uniform_value_pair dvec3_uniforms[] = {
7021 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3, stage_ptr->uniforms.uniform_dvec3),
7022 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[0],
7023 stage_ptr->uniforms.uniform_dvec3_arr + 0),
7024 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec3_arr[1],
7025 stage_ptr->uniforms.uniform_dvec3_arr + 3),
7026 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec3,
7027 stage_ptr->uniform_structure_arrays[0].uniform_dvec3),
7028 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec3,
7029 stage_ptr->uniform_structure_arrays[1].uniform_dvec3)
7031 const uniform_value_pair dvec4_uniforms[] = {
7032 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4, stage_ptr->uniforms.uniform_dvec4),
7033 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[0],
7034 stage_ptr->uniforms.uniform_dvec4_arr + 0),
7035 uniform_value_pair(stage_ptr->uniforms.uniform_location_dvec4_arr[1],
7036 stage_ptr->uniforms.uniform_dvec4_arr + 4),
7037 uniform_value_pair(stage_ptr->uniform_structure_arrays[0].uniform_location_dvec4,
7038 stage_ptr->uniform_structure_arrays[0].uniform_dvec4),
7039 uniform_value_pair(stage_ptr->uniform_structure_arrays[1].uniform_location_dvec4,
7040 stage_ptr->uniform_structure_arrays[1].uniform_dvec4)
7043 /* Iterate over all uniforms and verify the values reported by the API */
7044 double returned_double_data[4];
7045 float returned_float_data[4];
7046 int returned_int_data[4];
7047 unsigned int returned_uint_data[4];
7049 for (unsigned int n_type = 0; n_type < 4 /* double/dvec2/dvec3/dvec4 */; ++n_type)
7051 const uniform_value_pair* current_uv_pairs = NULL;
7052 const unsigned int n_components_used = n_type + 1; /* n_type=0: double, n_type=1: dvec2, etc.. */
7053 unsigned int n_pairs = 0;
7057 case 0: /* double */
7059 current_uv_pairs = double_uniforms;
7060 n_pairs = sizeof(double_uniforms) / sizeof(double_uniforms[0]);
7067 current_uv_pairs = dvec2_uniforms;
7068 n_pairs = sizeof(dvec2_uniforms) / sizeof(dvec2_uniforms[0]);
7075 current_uv_pairs = dvec3_uniforms;
7076 n_pairs = sizeof(dvec3_uniforms) / sizeof(dvec3_uniforms[0]);
7083 current_uv_pairs = dvec4_uniforms;
7084 n_pairs = sizeof(dvec4_uniforms) / sizeof(dvec4_uniforms[0]);
7091 TCU_FAIL("Invalid type index requested");
7093 } /* switch (n_type) */
7095 for (unsigned int n_pair = 0; n_pair < n_pairs; ++n_pair)
7097 const uniform_value_pair& current_uv_pair = current_uv_pairs[n_pair];
7098 glw::GLint uniform_location = current_uv_pair.first;
7099 const double* uniform_value = current_uv_pair.second;
7101 /* Retrieve the values from the GL implementation*/
7102 gl.getUniformdv(po_id, uniform_location, returned_double_data);
7103 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformdv() call failed.");
7105 gl.getUniformfv(po_id, uniform_location, returned_float_data);
7106 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformfv() call failed.");
7108 gl.getUniformiv(po_id, uniform_location, returned_int_data);
7109 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformiv() call failed.");
7111 gl.getUniformuiv(po_id, uniform_location, returned_uint_data);
7112 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformuiv() call failed.");
7114 /* Make sure the values reported match the reference values */
7115 bool can_continue = true;
7116 const float epsilon = 1e-5f;
7118 for (unsigned int n_component = 0; n_component < n_components_used && can_continue; ++n_component)
7120 if (de::abs(returned_double_data[n_component] - uniform_value[n_component]) > epsilon)
7123 << tcu::TestLog::Message
7124 << "Invalid uniform value reported by glGetUniformdv() for uniform location ["
7125 << uniform_location << "]"
7127 << n_component << "]"
7129 << returned_double_data[n_component] << "]"
7131 << uniform_value[n_component] << "]" << tcu::TestLog::EndMessage;
7136 if (de::abs(returned_float_data[n_component] - uniform_value[n_component]) > epsilon)
7139 << tcu::TestLog::Message
7140 << "Invalid uniform value reported by glGetUniformfv() for uniform location ["
7141 << uniform_location << "]"
7143 << n_component << "]"
7145 << returned_float_data[n_component] << "]"
7147 << uniform_value[n_component] << "]" << tcu::TestLog::EndMessage;
7153 int rounded_uniform_value_sint = (int)(deFloatRound((float)uniform_value[n_component]));
7154 unsigned int rounded_uniform_value_uint =
7155 (unsigned int)(uniform_value[n_component] > 0.0) ?
7156 ((unsigned int)deFloatRound((float)uniform_value[n_component])) :
7159 if (returned_int_data[n_component] != rounded_uniform_value_sint)
7162 << tcu::TestLog::Message
7163 << "Invalid uniform value reported by glGetUniformiv() for uniform location ["
7164 << uniform_location << "]"
7166 << n_component << "]"
7168 << returned_int_data[n_component] << "]"
7170 << rounded_uniform_value_sint << "]" << tcu::TestLog::EndMessage;
7175 if (returned_uint_data[n_component] != rounded_uniform_value_uint)
7178 << tcu::TestLog::Message
7179 << "Invalid uniform value reported by glGetUniformuiv() for uniform location ["
7180 << uniform_location << "]"
7182 << n_component << "]"
7184 << returned_uint_data[n_component] << "]"
7186 << rounded_uniform_value_uint << "]" << tcu::TestLog::EndMessage;
7190 } /* for (all components) */
7191 } /* for (all uniform+value pairs) */
7192 } /* for (all 4 uniform types) */
7193 } /* for (all shader stages) */
7194 } /* for (both program objects) */
7202 * @param context Rendering context.
7204 GPUShaderFP64Test5::GPUShaderFP64Test5(deqp::Context& context)
7205 : TestCase(context, "conversions", "Verifies explicit and implicit casts involving double-precision"
7206 " floating-point variables work correctly")
7207 , m_base_value_bo_data(DE_NULL)
7208 , m_base_value_bo_id(0)
7209 , m_has_test_passed(true)
7210 , m_po_base_value_attribute_location(-1)
7217 /* Set up base value array (as per test spec) */
7218 m_base_values[0] = -25.12065f;
7219 m_base_values[1] = 0.0f;
7220 m_base_values[2] = 0.001f;
7221 m_base_values[3] = 1.0f;
7222 m_base_values[4] = 256.78901f;
7224 /* Set up swizzle matrix */
7225 m_swizzle_matrix[0][0] = SWIZZLE_TYPE_NONE;
7226 m_swizzle_matrix[0][1] = SWIZZLE_TYPE_Y;
7227 m_swizzle_matrix[0][2] = SWIZZLE_TYPE_Z;
7228 m_swizzle_matrix[0][3] = SWIZZLE_TYPE_W;
7229 m_swizzle_matrix[1][0] = SWIZZLE_TYPE_NONE;
7230 m_swizzle_matrix[1][1] = SWIZZLE_TYPE_YX;
7231 m_swizzle_matrix[1][2] = SWIZZLE_TYPE_ZY;
7232 m_swizzle_matrix[1][3] = SWIZZLE_TYPE_WX;
7233 m_swizzle_matrix[2][0] = SWIZZLE_TYPE_NONE;
7234 m_swizzle_matrix[2][1] = SWIZZLE_TYPE_YXX;
7235 m_swizzle_matrix[2][2] = SWIZZLE_TYPE_XZY;
7236 m_swizzle_matrix[2][3] = SWIZZLE_TYPE_XWZY;
7237 m_swizzle_matrix[3][0] = SWIZZLE_TYPE_NONE;
7238 m_swizzle_matrix[3][1] = SWIZZLE_TYPE_YXXY;
7239 m_swizzle_matrix[3][2] = SWIZZLE_TYPE_XZXY;
7240 m_swizzle_matrix[3][3] = SWIZZLE_TYPE_XZYW;
7243 void GPUShaderFP64Test5::deinit()
7245 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7247 if (m_base_value_bo_data != DE_NULL)
7249 delete[] m_base_value_bo_data;
7251 m_base_value_bo_data = DE_NULL;
7254 if (m_base_value_bo_id != 0)
7256 gl.deleteBuffers(1, &m_base_value_bo_id);
7258 m_base_value_bo_id = 0;
7263 gl.deleteVertexArrays(1, &m_vao_id);
7268 if (m_xfb_bo_id != 0)
7270 gl.deleteBuffers(1, &m_xfb_bo_id);
7275 /* TCU_FAIL will skip the per sub test iteration de-initialization, we need to
7276 * take care of it here
7281 /** Deinitializes all buffers and GL objects that may have been generated
7282 * during test execution.
7284 void GPUShaderFP64Test5::deinitInteration()
7286 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7290 gl.deleteProgram(m_po_id);
7297 gl.deleteShader(m_vs_id);
7303 /** Executes a single test case iteration using user-provided test case descriptor.
7305 * This function may throw a TestError exception if GL implementation misbehaves.
7307 * @param test_case Test case descriptor to use.
7309 * @return true if the values returned by GL implementation were found to be valid,
7312 bool GPUShaderFP64Test5::executeIteration(const _test_case& test_case)
7316 /* Convert the base values array to the type of input attribute we'll be using
7317 * for the iteration.
7319 Utils::_variable_type base_value_type = Utils::getBaseVariableType(test_case.src_type);
7321 if (base_value_type == Utils::VARIABLE_TYPE_BOOL)
7323 /* bools are actually represented by ints, since bool varyings are not allowed */
7324 base_value_type = Utils::VARIABLE_TYPE_INT;
7327 const unsigned int base_value_component_size = Utils::getBaseVariableTypeComponentSize(base_value_type);
7328 const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]);
7330 m_base_value_bo_data = new unsigned char[base_value_component_size * n_base_values];
7332 unsigned char* base_value_traveller_ptr = m_base_value_bo_data;
7334 for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value)
7336 switch (base_value_type)
7338 case Utils::VARIABLE_TYPE_DOUBLE:
7339 *((double*)base_value_traveller_ptr) = (double)m_base_values[n_base_value];
7341 case Utils::VARIABLE_TYPE_FLOAT:
7342 *((float*)base_value_traveller_ptr) = (float)m_base_values[n_base_value];
7344 case Utils::VARIABLE_TYPE_INT:
7345 *((int*)base_value_traveller_ptr) = (int)m_base_values[n_base_value];
7347 case Utils::VARIABLE_TYPE_UINT:
7348 *((unsigned int*)base_value_traveller_ptr) = (unsigned int)m_base_values[n_base_value];
7353 TCU_FAIL("Unrecognized base value type");
7357 base_value_traveller_ptr += base_value_component_size;
7358 } /* for (all base values) */
7360 /* Update buffer object storage with the data we've just finished preparing. */
7361 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7363 gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id);
7364 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
7366 gl.bufferSubData(GL_ARRAY_BUFFER, 0 /* offset */, base_value_component_size * n_base_values, m_base_value_bo_data);
7367 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
7369 /* Configure vertex attribute array corresponding to 'base_value' attribute, so that the
7370 * new data is interpreted correctly.
7372 if (base_value_type == Utils::VARIABLE_TYPE_FLOAT)
7374 gl.vertexAttribPointer(m_po_base_value_attribute_location, 1, /* size */
7375 Utils::getGLDataTypeOfBaseVariableType(base_value_type), GL_FALSE, /* normalized */
7377 DE_NULL); /* pointer */
7378 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() call failed.");
7380 else if (base_value_type == Utils::VARIABLE_TYPE_INT || base_value_type == Utils::VARIABLE_TYPE_UINT)
7382 gl.vertexAttribIPointer(m_po_base_value_attribute_location, 1, /* size */
7383 Utils::getGLDataTypeOfBaseVariableType(base_value_type), 0, /* stride */
7384 DE_NULL); /* pointer */
7385 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer() call failed.");
7389 DE_ASSERT(base_value_type == Utils::VARIABLE_TYPE_DOUBLE);
7391 gl.vertexAttribLPointer(m_po_base_value_attribute_location, 1, /* size */
7392 GL_DOUBLE, 0, /* stride */
7393 DE_NULL); /* pointer */
7394 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertxAttribLPointer() call failed.");
7397 gl.enableVertexAttribArray(m_po_base_value_attribute_location);
7398 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() call failed.");
7400 /* Execute the draw call */
7401 gl.useProgram(m_po_id);
7402 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
7404 gl.beginTransformFeedback(GL_POINTS);
7405 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
7407 gl.drawArrays(GL_POINTS, 0 /* first */, n_base_values);
7408 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
7410 gl.endTransformFeedback();
7411 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
7413 /* Map the XFB buffer object into process space */
7414 void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
7416 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
7417 DE_ASSERT(xfb_data_ptr != NULL);
7419 /* Verify the data */
7420 result &= verifyXFBData((const unsigned char*)xfb_data_ptr, test_case);
7422 /* Unmap the XFB BO */
7423 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
7424 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
7426 /** Good to release the data buffer at this point */
7427 if (m_base_value_bo_data != DE_NULL)
7429 delete[] m_base_value_bo_data;
7431 m_base_value_bo_data = DE_NULL;
7438 /** Returns properties of a swizzle operator described by @param type swizzle type.
7440 * @param out_swizzle_string Deref will be used to store a GLSL literal
7441 * corresponding to the specific swizzle operator.
7443 * @param out_n_components Deref will be used to store the amount of components
7444 * used by the operator. Must not be NULL.
7445 * @param out_component_order Deref will be used to store up to 4 integer values,
7446 * corresponding to component indices described by the
7447 * operator for a particular position. Must not be NULL.
7449 void GPUShaderFP64Test5::getSwizzleTypeProperties(_swizzle_type type, std::string* out_swizzle_string,
7450 unsigned int* out_n_components, unsigned int* out_component_order)
7452 unsigned int result_component_order[4] = { 0 };
7453 unsigned int result_n_components = 0;
7454 std::string result_swizzle_string;
7458 case SWIZZLE_TYPE_NONE:
7460 result_swizzle_string = "";
7461 result_n_components = 0;
7466 case SWIZZLE_TYPE_XWZY:
7468 result_swizzle_string = "xwzy";
7469 result_n_components = 4;
7470 result_component_order[0] = 0;
7471 result_component_order[1] = 3;
7472 result_component_order[2] = 2;
7473 result_component_order[3] = 1;
7478 case SWIZZLE_TYPE_XZXY:
7480 result_swizzle_string = "xzxy";
7481 result_n_components = 4;
7482 result_component_order[0] = 0;
7483 result_component_order[1] = 2;
7484 result_component_order[2] = 0;
7485 result_component_order[3] = 1;
7490 case SWIZZLE_TYPE_XZY:
7492 result_swizzle_string = "xzy";
7493 result_n_components = 3;
7494 result_component_order[0] = 0;
7495 result_component_order[1] = 2;
7496 result_component_order[2] = 1;
7501 case SWIZZLE_TYPE_XZYW:
7503 result_swizzle_string = "xzyw";
7504 result_n_components = 4;
7505 result_component_order[0] = 0;
7506 result_component_order[1] = 2;
7507 result_component_order[2] = 1;
7508 result_component_order[3] = 3;
7513 case SWIZZLE_TYPE_Y:
7515 result_swizzle_string = "y";
7516 result_n_components = 1;
7517 result_component_order[0] = 1;
7522 case SWIZZLE_TYPE_YX:
7524 result_swizzle_string = "yx";
7525 result_n_components = 2;
7526 result_component_order[0] = 1;
7527 result_component_order[1] = 0;
7532 case SWIZZLE_TYPE_YXX:
7534 result_swizzle_string = "yxx";
7535 result_n_components = 3;
7536 result_component_order[0] = 1;
7537 result_component_order[1] = 0;
7538 result_component_order[2] = 0;
7543 case SWIZZLE_TYPE_YXXY:
7545 result_swizzle_string = "yxxy";
7546 result_n_components = 4;
7547 result_component_order[0] = 1;
7548 result_component_order[1] = 0;
7549 result_component_order[2] = 0;
7550 result_component_order[3] = 1;
7555 case SWIZZLE_TYPE_Z:
7557 result_swizzle_string = "z";
7558 result_n_components = 1;
7559 result_component_order[0] = 2;
7564 case SWIZZLE_TYPE_ZY:
7566 result_swizzle_string = "zy";
7567 result_n_components = 2;
7568 result_component_order[0] = 2;
7569 result_component_order[1] = 1;
7574 case SWIZZLE_TYPE_W:
7576 result_swizzle_string = "w";
7577 result_n_components = 1;
7578 result_component_order[0] = 3;
7583 case SWIZZLE_TYPE_WX:
7585 result_swizzle_string = "wx";
7586 result_n_components = 2;
7587 result_component_order[0] = 3;
7588 result_component_order[1] = 0;
7595 TCU_FAIL("Unrecognized swizzle type");
7597 } /* switch (type) */
7599 if (out_swizzle_string != DE_NULL)
7601 *out_swizzle_string = result_swizzle_string;
7604 if (out_n_components != DE_NULL)
7606 *out_n_components = result_n_components;
7609 if (out_component_order != DE_NULL)
7611 memcpy(out_component_order, result_component_order, sizeof(unsigned int) * result_n_components);
7615 /** Returns body of a vertex shader that should be used for particular test case,
7616 * given user-specified test case descriptor.
7618 * @param test_case Descriptor to use for the query.
7620 * @return Requested data.
7622 std::string GPUShaderFP64Test5::getVertexShaderBody(const _test_case& test_case)
7624 std::stringstream result;
7625 const std::string base_type_string = Utils::getVariableTypeString(Utils::getBaseVariableType(test_case.src_type));
7626 const std::string dst_type_string = Utils::getVariableTypeString(test_case.dst_type);
7627 const unsigned int n_dst_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type);
7628 const unsigned int n_src_components = Utils::getNumberOfComponentsForVariableType(test_case.src_type);
7629 const std::string src_type_string = Utils::getVariableTypeString(test_case.src_type);
7631 /* Add version preamble */
7632 result << "#version 420\n"
7635 /* Declare output variables. Note that boolean output variables are not supported, so we need
7636 * to handle that special case correctly */
7637 if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL)
7639 result << "out int result;\n";
7643 result << "out " << dst_type_string << " result;\n";
7646 /* Declare input variables. Handle the bool case exclusively. */
7647 if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL)
7649 /* Use ints for bools. We will cast them to bool in the code later. */
7650 result << "in int base_value;\n";
7654 result << "in " << base_type_string << " base_value;\n";
7657 /* Declare main() and construct the value we will be casting from.
7659 * Note: Addition operations on bool values cause an implicit conversion to int
7660 * which is not allowed. Hence, we skip these operations for this special
7663 result << "void main()\n"
7665 << src_type_string << " lside_value = ";
7667 if (test_case.src_type == Utils::VARIABLE_TYPE_BOOL)
7669 result << src_type_string << "(0 != ";
7673 result << src_type_string << "(";
7676 if (test_case.src_type != Utils::VARIABLE_TYPE_BOOL)
7678 for (unsigned int n_component = 0; n_component < n_src_components; ++n_component)
7680 result << "base_value + " << n_component;
7682 if (n_component != (n_src_components - 1))
7686 } /* for (all components) */
7690 DE_ASSERT(n_src_components == 1);
7692 result << "base_value";
7697 /* Perform the casting operation. Add swizzle operator if possible. */
7698 if (test_case.dst_type == Utils::VARIABLE_TYPE_BOOL)
7700 /* Handle the bool case exclusively */
7701 if (test_case.type == TEST_CASE_TYPE_EXPLICIT)
7703 result << "result = (bool(lside_value) == false) ? 0 : 1";
7707 result << "result = (lside_value == false) ? 0 : 1";
7712 if (test_case.type == TEST_CASE_TYPE_EXPLICIT)
7714 result << "result = " << dst_type_string << "(lside_value)";
7718 result << "result = lside_value";
7722 if (n_src_components > 1 && !Utils::isMatrixVariableType(test_case.src_type))
7724 /* Add a swizzle operator */
7725 DE_ASSERT(n_dst_components > 0 && n_dst_components <= 4);
7726 DE_ASSERT(n_src_components > 0 && n_src_components <= 4);
7728 unsigned int swizzle_component_order[4] = { 0 };
7729 unsigned int swizzle_n_components = 0;
7730 _swizzle_type swizzle_operator = m_swizzle_matrix[n_dst_components - 1][n_src_components - 1];
7731 std::string swizzle_string;
7733 getSwizzleTypeProperties(swizzle_operator, &swizzle_string, &swizzle_n_components, swizzle_component_order);
7735 if (swizzle_n_components > 0)
7737 result << "." << swizzle_string;
7741 /* Close the shader implementation. */
7745 return result.str();
7748 /** Initializes program & shader objects needed to run the iteration, given
7749 * user-specified test case descriptor.
7751 * This function can throw a TestError exception if a GL error is detected
7754 * @param test_case Descriptor to use for the iteration.
7756 void GPUShaderFP64Test5::initIteration(_test_case& test_case)
7758 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7760 /* Create program & shader objects */
7761 m_po_id = gl.createProgram();
7762 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
7764 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
7765 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
7767 /* Configure shader body */
7768 std::string body = getVertexShaderBody(test_case);
7769 const char* body_raw_ptr = body.c_str();
7771 gl.shaderSource(m_vs_id, 1 /* count */, &body_raw_ptr, DE_NULL /* length */);
7772 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
7774 /* Store it in the test case descriptor for logging purposes */
7775 test_case.shader_body = body;
7777 /* Compile the shader */
7778 glw::GLint compile_status = GL_FALSE;
7780 gl.compileShader(m_vs_id);
7781 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
7783 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
7784 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
7786 if (compile_status != GL_TRUE)
7788 TCU_FAIL("Shader compilation failed");
7791 /* Attach the shader to the program obejct */
7792 gl.attachShader(m_po_id, m_vs_id);
7793 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
7795 /* Configure XFB for the program object */
7796 const char* xfb_varying_name = "result";
7798 gl.transformFeedbackVaryings(m_po_id, 1 /* count */, &xfb_varying_name, GL_INTERLEAVED_ATTRIBS);
7799 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
7801 /* Link the program object */
7802 glw::GLint link_status = GL_FALSE;
7804 gl.linkProgram(m_po_id);
7805 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
7807 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
7808 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
7810 if (link_status != GL_TRUE)
7812 TCU_FAIL("Program linking failed");
7815 /* Retrieve attribute locations */
7816 m_po_base_value_attribute_location = gl.getAttribLocation(m_po_id, "base_value");
7817 GLU_EXPECT_NO_ERROR(gl.getError(), "getAttribLocation() call failed.");
7819 if (m_po_base_value_attribute_location == -1)
7821 TCU_FAIL("'base_value' is considered an inactive attribute which is invalid.");
7825 /** Initializes GL objects used by all test cases.
7827 * This function may throw a TestError exception if GL implementation reports
7828 * an error at any point.
7830 void GPUShaderFP64Test5::initTest()
7832 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7834 /* Generate buffer object IDs */
7835 gl.genBuffers(1, &m_base_value_bo_id);
7836 gl.genBuffers(1, &m_xfb_bo_id);
7837 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
7839 /* Allocate buffer object storage for 'base_value' input attribute data. All iterations
7840 * will never eat up more than 1 double (as per test spec) and we will be drawing
7841 * as many points in a single draw call as there are defined in m_base_values array.
7843 const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]);
7845 gl.bindBuffer(GL_ARRAY_BUFFER, m_base_value_bo_id);
7846 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
7848 gl.bufferData(GL_ARRAY_BUFFER, sizeof(double) * n_base_values, DE_NULL /* data */, GL_STATIC_DRAW);
7849 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
7851 /* Allocate buffer object storage for XFB data. For each iteratiom we will be using
7852 * five base values. Each XFBed value can take up to 16 components (eg. mat4) and be
7853 * of double type (eg. dmat4), so make sure a sufficient amount of space is requested.
7855 const unsigned int xfb_bo_size = sizeof(double) * 16 /* components */ * n_base_values;
7857 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
7858 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
7860 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
7861 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
7863 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
7864 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
7866 /* Allocate a client-side buffer to hold the data we will be mapping from XFB BO */
7867 m_xfb_bo_size = xfb_bo_size;
7869 /* Generate a vertex array object we will need to use for the draw calls */
7870 gl.genVertexArrays(1, &m_vao_id);
7871 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
7873 gl.bindVertexArray(m_vao_id);
7874 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
7877 /** Executes test iteration.
7879 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
7881 tcu::TestNode::IterateResult GPUShaderFP64Test5::iterate()
7883 /* Do not execute the test if GL_ARB_texture_view is not supported */
7884 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
7886 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
7889 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit"))
7891 throw tcu::NotSupportedError("GL_ARB_vertex_attrib_64bit is not supported.");
7894 /* Initialize GL objects needed to run the tests */
7897 /* Build iteration array to run the tests in an automated manner */
7898 _test_case test_cases[] = {
7899 /* test case type */ /* source type */ /* destination type */
7900 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" },
7901 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
7902 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
7903 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
7904 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" },
7905 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
7906 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
7907 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
7908 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" },
7909 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, "" },
7910 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, "" },
7911 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, "" },
7912 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, "" },
7913 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, "" },
7914 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, "" },
7915 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, "" },
7916 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, "" },
7917 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, "" },
7918 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, "" },
7919 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, "" },
7920 { TEST_CASE_TYPE_IMPLICIT, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, "" },
7922 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, "" },
7923 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, "" },
7924 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, "" },
7925 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_INT, "" },
7926 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_UINT, "" },
7927 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_FLOAT, "" },
7928 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_BOOL, "" },
7929 { TEST_CASE_TYPE_EXPLICIT, Utils::VARIABLE_TYPE_BOOL, Utils::VARIABLE_TYPE_DOUBLE, "" }
7931 const unsigned int n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
7933 /* Execute all iterations */
7934 for (unsigned int n_test_case = 0; n_test_case < n_test_cases; ++n_test_case)
7936 _test_case& test_case = test_cases[n_test_case];
7938 /* Initialize a program object we will use to perform the casting */
7939 initIteration(test_case);
7941 /* Use the program object to XFB the results */
7942 m_has_test_passed &= executeIteration(test_case);
7944 /* Release the GL Resource for this sub test */
7947 } /* for (all test cases) */
7949 if (m_has_test_passed)
7951 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7955 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7961 /** Verifies if data XFBed out by the vertex shader are valid, given test case descriptor,
7962 * for which the data have been generated.
7964 * @param data_ptr Buffer holding the data XFBed out by the shader.
7965 * @param test_case Descriptor of the test case, for which the vertex shader was
7968 * @return true if the data were found to be valid, false otherwise.
7970 bool GPUShaderFP64Test5::verifyXFBData(const unsigned char* data_ptr, const _test_case& test_case)
7972 const Utils::_variable_type base_dst_type = Utils::getBaseVariableType(test_case.dst_type);
7973 const Utils::_variable_type base_src_type = Utils::getBaseVariableType(test_case.src_type);
7974 const float epsilon = 1e-5f;
7975 const unsigned int n_base_values = sizeof(m_base_values) / sizeof(m_base_values[0]);
7976 const unsigned int n_result_components = Utils::getNumberOfComponentsForVariableType(test_case.dst_type);
7977 const unsigned int n_src_components = Utils::getNumberOfComponentsForVariableType(test_case.src_type);
7979 _swizzle_type swizzle_operator = SWIZZLE_TYPE_NONE;
7980 unsigned int swizzle_order[4] = { 0 };
7981 const unsigned char* traveller_ptr = data_ptr;
7983 if (!Utils::isMatrixVariableType(test_case.src_type))
7985 DE_ASSERT(n_result_components >= 1 && n_result_components <= 4);
7986 DE_ASSERT(n_src_components >= 1 && n_src_components <= 4);
7988 swizzle_operator = m_swizzle_matrix[n_result_components - 1][n_src_components - 1];
7990 getSwizzleTypeProperties(swizzle_operator, DE_NULL, /* out_swizzle_string */
7991 DE_NULL, /* out_n_components */
7995 for (unsigned int n_base_value = 0; n_base_value < n_base_values; ++n_base_value)
7997 for (unsigned int n_result_component = 0; n_result_component < n_result_components; ++n_result_component)
7999 unsigned int n_swizzled_component = n_result_component;
8001 if (swizzle_operator != SWIZZLE_TYPE_NONE)
8003 n_swizzled_component =
8004 (n_result_component / n_result_components) * n_result_component + swizzle_order[n_result_component];
8007 switch (base_dst_type)
8009 case Utils::VARIABLE_TYPE_BOOL:
8010 case Utils::VARIABLE_TYPE_INT:
8012 double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component);
8013 double expected_value = ref_expected_value;
8014 int result_value = *((int*)traveller_ptr);
8016 if (base_dst_type == Utils::VARIABLE_TYPE_BOOL)
8018 if (expected_value != 0.0)
8020 expected_value = 1.0;
8024 if (result_value != (int)expected_value)
8026 m_testCtx.getLog() << tcu::TestLog::Message
8027 << "Invalid boolean/integer value obtained when doing an "
8028 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
8029 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
8031 ", component index: ["
8032 << n_swizzled_component << "]"
8034 << ref_expected_value << "]"
8036 << Utils::getVariableTypeString(test_case.dst_type) << "]"
8037 ", retrieved value: ["
8038 << result_value << "]"
8039 ", expected value: ["
8040 << (int)expected_value << "]"
8042 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
8047 traveller_ptr += sizeof(int);
8049 } /* VARIABLE_TYPE_BOOL or VARIABLE_TYPE_INT cases */
8051 case Utils::VARIABLE_TYPE_DOUBLE:
8053 double ref_expected_value = m_base_values[n_base_value] + (double)n_swizzled_component;
8054 double expected_value = ref_expected_value;
8055 double result_value = *((double*)traveller_ptr);
8057 if (base_src_type == Utils::VARIABLE_TYPE_BOOL)
8059 expected_value = ((int)expected_value != 0.0) ? 1.0 : 0.0;
8061 else if (base_src_type == Utils::VARIABLE_TYPE_INT)
8063 expected_value = (int)expected_value;
8065 else if (base_src_type == Utils::VARIABLE_TYPE_UINT)
8067 // Negative values in base values array when converted to unsigned int will be ZERO
8068 // Addition operations done inside the shader in such cases will operate on ZERO rather
8069 // than the negative value being passed.
8070 // Replicate the sequence of conversion and addition operations done on the
8071 // shader input, to calculate the expected values in XFB data in the
8072 // problematic cases.
8073 if (expected_value < 0)
8075 expected_value = (unsigned int)m_base_values[n_base_value] + n_swizzled_component;
8077 expected_value = (unsigned int)expected_value;
8080 traveller_ptr += sizeof(double);
8081 if (de::abs(result_value - expected_value) > epsilon)
8083 m_testCtx.getLog() << tcu::TestLog::Message
8084 << "Invalid double-precision floating-point value obtained when doing an "
8085 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
8086 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
8088 ", component index: ["
8089 << n_swizzled_component << "]"
8091 << ref_expected_value << "]"
8093 << Utils::getVariableTypeString(test_case.dst_type) << "]"
8094 ", retrieved value: ["
8095 << std::setprecision(16) << result_value << "]"
8096 ", expected value: ["
8097 << std::setprecision(16) << expected_value << "]"
8099 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
8105 } /* VARIABLE_TYPE_DOUBLE case */
8107 case Utils::VARIABLE_TYPE_FLOAT:
8109 float ref_expected_value = (float)m_base_values[n_base_value] + (float)n_swizzled_component;
8110 float expected_value = ref_expected_value;
8111 float result_value = *((float*)traveller_ptr);
8113 if (base_src_type == Utils::VARIABLE_TYPE_BOOL)
8115 expected_value = (expected_value != 0.0f) ? 1.0f : 0.0f;
8117 else if (base_src_type == Utils::VARIABLE_TYPE_INT)
8119 expected_value = (float)((int)expected_value);
8121 else if (base_src_type == Utils::VARIABLE_TYPE_UINT)
8123 expected_value = (float)((unsigned int)expected_value);
8126 traveller_ptr += sizeof(float);
8127 if (de::abs(result_value - expected_value) > epsilon)
8129 m_testCtx.getLog() << tcu::TestLog::Message
8130 << "Invalid single-precision floating-point value obtained when doing an "
8131 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
8132 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
8134 ", component index: ["
8135 << n_swizzled_component << "]"
8137 << ref_expected_value << "]"
8139 << Utils::getVariableTypeString(test_case.dst_type) << "]"
8140 ", retrieved value: ["
8141 << std::setprecision(16) << result_value << "]"
8142 ", expected value: ["
8143 << std::setprecision(16) << expected_value << "]"
8145 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
8151 } /* VARIABLE_TYPE_FLOAT case */
8153 case Utils::VARIABLE_TYPE_UINT:
8155 double ref_expected_value = (m_base_values[n_base_value]) + static_cast<float>(n_swizzled_component);
8156 double expected_value = ref_expected_value;
8157 unsigned int result_value = *((unsigned int*)traveller_ptr);
8159 traveller_ptr += sizeof(unsigned int);
8160 if (result_value != (unsigned int)expected_value)
8162 if (expected_value < 0.0)
8164 // It is undefined to convert a negative floating-point value to an uint.
8168 m_testCtx.getLog() << tcu::TestLog::Message
8169 << "Invalid unsigned integer value obtained when doing an "
8170 << ((test_case.type == TEST_CASE_TYPE_EXPLICIT) ? "explicit" : "implicit")
8171 << " cast from GLSL type [" << Utils::getVariableTypeString(test_case.src_type)
8173 ", component index: ["
8174 << n_swizzled_component << "]"
8176 << ref_expected_value << "]"
8178 << Utils::getVariableTypeString(test_case.dst_type) << "]"
8179 ", retrieved value: ["
8180 << result_value << "]"
8181 ", expected value: ["
8182 << (unsigned int)expected_value << "]"
8184 << test_case.shader_body.c_str() << tcu::TestLog::EndMessage;
8190 } /* VARIABLE_TYPE_UINT case */
8194 TCU_FAIL("Unrecognized variable type");
8196 } /* switch (test_case.dst_type) */
8197 } /* for (all result components) */
8198 } /* for (all base values) */
8205 * @param context Rendering context.
8207 GPUShaderFP64Test6::GPUShaderFP64Test6(deqp::Context& context)
8208 : TestCase(context, "illegal_conversions", "Verifies that invalid casts to double-precision variables are detected "
8209 "during compilation time.")
8216 , m_has_test_passed(true)
8220 /** Deinitializes all buffers and GL objects that may have been generated
8221 * during test execution.
8223 void GPUShaderFP64Test6::deinit()
8225 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8229 gl.deleteShader(m_cs_id);
8236 gl.deleteShader(m_fs_id);
8243 gl.deleteShader(m_gs_id);
8250 gl.deleteShader(m_tc_id);
8257 gl.deleteShader(m_te_id);
8264 gl.deleteShader(m_vs_id);
8270 /** Executes a single test case.
8272 * This function can throw TestError exceptions if GL implementation reports
8275 * @param test_case Test case descriptor.
8277 * @return true if test case passed, false otherwise.
8279 bool GPUShaderFP64Test6::executeIteration(const _test_case& test_case)
8281 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8282 const glw::GLuint so_ids[] = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
8283 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
8285 const char* stage_body = NULL;
8286 const char* stage_name = NULL;
8288 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
8290 const glw::GLuint so_id = so_ids[n_so_id];
8292 /* Skip compute shader if it is not supported */
8298 /* Compile the shader */
8299 gl.compileShader(so_id);
8300 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
8302 /* Has the compilation failed as expected? */
8303 glw::GLint compile_status = GL_TRUE;
8305 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
8306 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
8308 if (compile_status == GL_TRUE)
8310 /* What is the current stage's name? */
8311 if (so_id == m_cs_id)
8313 stage_body = test_case.cs_shader_body.c_str();
8314 stage_name = "Compute shader";
8316 else if (so_id == m_fs_id)
8318 stage_body = test_case.fs_shader_body.c_str();
8319 stage_name = "Fragment shader";
8321 else if (so_id == m_gs_id)
8323 stage_body = test_case.gs_shader_body.c_str();
8324 stage_name = "Geometry shader";
8326 else if (so_id == m_tc_id)
8328 stage_body = test_case.tc_shader_body.c_str();
8329 stage_name = "Tessellation control shader";
8331 else if (so_id == m_te_id)
8333 stage_body = test_case.te_shader_body.c_str();
8334 stage_name = "Tessellation evaluation shader";
8336 else if (so_id == m_vs_id)
8338 stage_body = test_case.vs_shader_body.c_str();
8339 stage_name = "Vertex shader";
8343 /* Doesn't make much sense to throw exceptions here so.. */
8348 /* This shader should have never compiled successfully! */
8349 m_testCtx.getLog() << tcu::TestLog::Message << stage_name
8350 << " has been compiled successfully, even though the shader was malformed."
8351 " Following is shader body:\n"
8352 << stage_body << tcu::TestLog::EndMessage;
8356 } /* for (all shader objects) */
8361 /** Retrieves body of a compute shader that should be used for the purpose of
8362 * user-specified test case.
8364 * @param test_case Test case descriptor to use.
8366 * @return Requested string.
8368 std::string GPUShaderFP64Test6::getComputeShaderBody(const _test_case& test_case)
8370 std::stringstream result_sstream;
8373 result_sstream << "#version 420\n"
8374 "#extension GL_ARB_compute_shader : require\n"
8376 "layout(local_size_x = 6) in;\n"
8381 /* Add local variable declarations */
8382 result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
8384 if (test_case.src_array_size > 1)
8386 result_sstream << "[" << test_case.src_array_size << "]";
8389 result_sstream << ";\n";
8391 if (test_case.wrap_dst_type_in_structure)
8393 result_sstream << "struct\n"
8395 << Utils::getVariableTypeString(test_case.dst_type) << " member";
8399 result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
8402 result_sstream << ";\n";
8404 if (test_case.wrap_dst_type_in_structure)
8406 result_sstream << "\n} dst;\n";
8409 /* Add actual body */
8410 result_sstream << "dst = src;\n"
8413 /* Return the body */
8414 return result_sstream.str();
8417 /** Retrieves body of a fragment shader that should be used for the purpose of
8418 * user-specified test case.
8420 * @param test_case Test case descriptor to use.
8422 * @return Requested string.
8424 std::string GPUShaderFP64Test6::getFragmentShaderBody(const _test_case& test_case)
8426 std::stringstream result_sstream;
8429 result_sstream << "#version 420\n"
8434 /* Add local variable declarations */
8435 result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
8437 if (test_case.src_array_size > 1)
8439 result_sstream << "[" << test_case.src_array_size << "]";
8442 result_sstream << ";\n";
8444 if (test_case.wrap_dst_type_in_structure)
8446 result_sstream << "struct\n"
8448 << Utils::getVariableTypeString(test_case.dst_type) << " member";
8452 result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
8455 result_sstream << ";\n";
8457 if (test_case.wrap_dst_type_in_structure)
8459 result_sstream << "\n} dst;\n";
8462 /* Add actual body */
8463 result_sstream << "dst = src;\n"
8466 /* Return the body */
8467 return result_sstream.str();
8470 /** Retrieves body of a geometry shader that should be used for the purpose of
8471 * user-specified test case.
8473 * @param test_case Test case descriptor to use.
8475 * @return Requested string.
8477 std::string GPUShaderFP64Test6::getGeometryShaderBody(const _test_case& test_case)
8479 std::stringstream result_sstream;
8482 result_sstream << "#version 420\n"
8484 "layout(points) in;\n"
8485 "layout(max_vertices=1, points) out;\n"
8490 /* Add local variable declarations */
8491 result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
8493 if (test_case.src_array_size > 1)
8495 result_sstream << "[" << test_case.src_array_size << "]";
8498 result_sstream << ";\n";
8500 if (test_case.wrap_dst_type_in_structure)
8502 result_sstream << "struct\n"
8504 << Utils::getVariableTypeString(test_case.dst_type) << " member";
8508 result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
8511 result_sstream << ";\n"
8514 if (test_case.wrap_dst_type_in_structure)
8516 result_sstream << "} dst;\n";
8519 /* Add actual body */
8520 result_sstream << "dst = src;\n"
8524 return result_sstream.str();
8527 /** Retrieves body of a tesellation control shader that should be used for the purpose of
8528 * user-specified test case.
8530 * @param test_case Test case descriptor to use.
8532 * @return Requested string.
8534 std::string GPUShaderFP64Test6::getTessellationControlShaderBody(const _test_case& test_case)
8536 std::stringstream result_sstream;
8539 result_sstream << "#version 420\n"
8541 "layout(vertices=4) out;\n"
8546 /* Add local variable declarations. */
8547 result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
8549 if (test_case.src_array_size > 1)
8551 result_sstream << "[" << test_case.src_array_size << "]";
8554 result_sstream << ";\n";
8556 if (test_case.wrap_dst_type_in_structure)
8558 result_sstream << "struct\n"
8560 << Utils::getVariableTypeString(test_case.dst_type) << " member";
8564 result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
8567 if (test_case.wrap_dst_type_in_structure)
8569 result_sstream << ";\n"
8574 result_sstream << ";\n";
8577 /* Continue with the actual body. */
8578 result_sstream << "gl_TessLevelOuter[0] = 1.0;\n"
8579 "gl_TessLevelOuter[1] = 1.0;\n"
8583 /* Return the body */
8584 return result_sstream.str();
8587 /** Retrieves body of a tessellation evaluation shader that should be used for the purpose of
8588 * user-specified test case.
8590 * @param test_case Test case descriptor to use.
8592 * @return Requested string.
8594 std::string GPUShaderFP64Test6::getTessellationEvaluationShaderBody(const _test_case& test_case)
8596 std::stringstream result_sstream;
8599 result_sstream << "#version 420\n"
8601 "layout(isolines) in;\n"
8606 /* Add local variable declarations */
8607 result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
8609 if (test_case.src_array_size > 1)
8611 result_sstream << "[" << test_case.src_array_size << "]";
8614 result_sstream << ";\n";
8616 if (test_case.wrap_dst_type_in_structure)
8618 result_sstream << "struct\n"
8620 << Utils::getVariableTypeString(test_case.dst_type) << " member";
8624 result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
8627 if (test_case.wrap_dst_type_in_structure)
8629 result_sstream << ";\n"
8634 result_sstream << ";\n";
8637 /* Continue with the actual body. */
8638 result_sstream << "dst = src;\n";
8640 /* Complete the body */
8641 result_sstream << "}\n";
8643 /* Return the body */
8644 return result_sstream.str();
8647 /** Retrieves body of a vertex shader that should be used for the purpose of
8648 * user-specified test case.
8650 * @param test_case Test case descriptor to use.
8652 * @return Requested string.
8654 std::string GPUShaderFP64Test6::getVertexShaderBody(const _test_case& test_case)
8656 std::stringstream result_sstream;
8659 result_sstream << "#version 420\n"
8664 /* Add local variables */
8665 result_sstream << Utils::getVariableTypeString(test_case.src_type) << " src";
8667 if (test_case.src_array_size > 1)
8669 result_sstream << "[" << test_case.src_array_size << "]";
8672 result_sstream << ";\n";
8674 if (test_case.wrap_dst_type_in_structure)
8676 result_sstream << "struct\n"
8678 << Utils::getVariableTypeString(test_case.dst_type) << " member";
8682 result_sstream << Utils::getVariableTypeString(test_case.dst_type) << " dst";
8685 if (test_case.wrap_dst_type_in_structure)
8687 result_sstream << ";\n"
8692 result_sstream << ";\n";
8695 /* Start actual body */
8696 result_sstream << "dst = src;\n"
8697 "gl_Position = vec4(1.0);\n"
8700 return result_sstream.str();
8703 /** Initializes shader objects required to run the test. */
8704 void GPUShaderFP64Test6::initTest()
8706 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8708 /* Generate shader objects */
8710 /* Compute shader support and GL 4.2 required */
8711 if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
8712 (true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
8714 m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
8717 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
8718 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
8719 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
8720 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
8721 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
8723 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
8726 /** Assigns shader bodies to all shader objects that will be used for a single iteration.
8728 * @param test_case Test case descriptor to generate the shader bodies for.
8730 void GPUShaderFP64Test6::initIteration(_test_case& test_case)
8732 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8734 test_case.cs_shader_body = getComputeShaderBody(test_case);
8735 test_case.fs_shader_body = getFragmentShaderBody(test_case);
8736 test_case.gs_shader_body = getGeometryShaderBody(test_case);
8737 test_case.tc_shader_body = getTessellationControlShaderBody(test_case);
8738 test_case.te_shader_body = getTessellationEvaluationShaderBody(test_case);
8739 test_case.vs_shader_body = getVertexShaderBody(test_case);
8741 /* Assign the bodies to relevant shaders */
8742 const char* cs_body_raw_ptr = test_case.cs_shader_body.c_str();
8743 const char* fs_body_raw_ptr = test_case.fs_shader_body.c_str();
8744 const char* gs_body_raw_ptr = test_case.gs_shader_body.c_str();
8745 const char* tc_body_raw_ptr = test_case.tc_shader_body.c_str();
8746 const char* te_body_raw_ptr = test_case.te_shader_body.c_str();
8747 const char* vs_body_raw_ptr = test_case.vs_shader_body.c_str();
8749 /* m_cs_id is initialized only if compute_shader is supported */
8752 gl.shaderSource(m_cs_id, 1 /* count */, &cs_body_raw_ptr, DE_NULL /* length */);
8755 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, DE_NULL /* length */);
8756 gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, DE_NULL /* length */);
8757 gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, DE_NULL /* length */);
8758 gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, DE_NULL /* length */);
8759 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
8760 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
8763 /** Executes test iteration.
8765 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
8767 tcu::TestNode::IterateResult GPUShaderFP64Test6::iterate()
8769 /* Do not execute the test if GL_ARB_texture_view is not supported */
8770 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
8772 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
8775 /* Initialize GL objects needed to run the tests */
8778 /* Build iteration array to run the tests in an automated manner */
8779 _test_case test_cases[] = {
8780 /* Src array size */ /* Src type */ /* Dst type */ /* wrap_dst_type_in_structure */
8781 { 2, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
8782 { 2, Utils::VARIABLE_TYPE_INT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
8783 { 2, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
8784 { 2, Utils::VARIABLE_TYPE_IVEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
8785 { 2, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
8786 { 2, Utils::VARIABLE_TYPE_IVEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
8787 { 2, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
8788 { 2, Utils::VARIABLE_TYPE_IVEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
8789 { 2, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
8790 { 2, Utils::VARIABLE_TYPE_UINT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
8791 { 2, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
8792 { 2, Utils::VARIABLE_TYPE_UVEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
8793 { 2, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
8794 { 2, Utils::VARIABLE_TYPE_UVEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
8795 { 2, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
8796 { 2, Utils::VARIABLE_TYPE_UVEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
8797 { 2, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, false, "", "", "", "", "", "" },
8798 { 2, Utils::VARIABLE_TYPE_FLOAT, Utils::VARIABLE_TYPE_DOUBLE, true, "", "", "", "", "", "" },
8799 { 2, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, false, "", "", "", "", "", "" },
8800 { 2, Utils::VARIABLE_TYPE_VEC2, Utils::VARIABLE_TYPE_DVEC2, true, "", "", "", "", "", "" },
8801 { 2, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, false, "", "", "", "", "", "" },
8802 { 2, Utils::VARIABLE_TYPE_VEC3, Utils::VARIABLE_TYPE_DVEC3, true, "", "", "", "", "", "" },
8803 { 2, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, false, "", "", "", "", "", "" },
8804 { 2, Utils::VARIABLE_TYPE_VEC4, Utils::VARIABLE_TYPE_DVEC4, true, "", "", "", "", "", "" },
8805 { 2, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, false, "", "", "", "", "", "" },
8806 { 2, Utils::VARIABLE_TYPE_MAT2, Utils::VARIABLE_TYPE_DMAT2, true, "", "", "", "", "", "" },
8807 { 2, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, false, "", "", "", "", "", "" },
8808 { 2, Utils::VARIABLE_TYPE_MAT3, Utils::VARIABLE_TYPE_DMAT3, true, "", "", "", "", "", "" },
8809 { 2, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, false, "", "", "", "", "", "" },
8810 { 2, Utils::VARIABLE_TYPE_MAT4, Utils::VARIABLE_TYPE_DMAT4, true, "", "", "", "", "", "" },
8811 { 2, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, false, "", "", "", "", "", "" },
8812 { 2, Utils::VARIABLE_TYPE_MAT2X3, Utils::VARIABLE_TYPE_DMAT2X3, true, "", "", "", "", "", "" },
8813 { 2, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, false, "", "", "", "", "", "" },
8814 { 2, Utils::VARIABLE_TYPE_MAT2X4, Utils::VARIABLE_TYPE_DMAT2X4, true, "", "", "", "", "", "" },
8815 { 2, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, false, "", "", "", "", "", "" },
8816 { 2, Utils::VARIABLE_TYPE_MAT3X2, Utils::VARIABLE_TYPE_DMAT3X2, true, "", "", "", "", "", "" },
8817 { 2, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, false, "", "", "", "", "", "" },
8818 { 2, Utils::VARIABLE_TYPE_MAT3X4, Utils::VARIABLE_TYPE_DMAT3X4, true, "", "", "", "", "", "" },
8819 { 2, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, false, "", "", "", "", "", "" },
8820 { 2, Utils::VARIABLE_TYPE_MAT4X2, Utils::VARIABLE_TYPE_DMAT4X2, true, "", "", "", "", "", "" },
8821 { 2, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, false, "", "", "", "", "", "" },
8822 { 2, Utils::VARIABLE_TYPE_MAT4X3, Utils::VARIABLE_TYPE_DMAT4X3, true, "", "", "", "", "", "" }
8824 const unsigned int n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
8826 /* Execute all iterations */
8827 for (unsigned int n_test_case = 0; n_test_case < n_test_cases; ++n_test_case)
8829 _test_case& test_case = test_cases[n_test_case];
8831 /* Initialize a program object we will use to perform the casting */
8832 initIteration(test_case);
8834 /* Use the program object to XFB the results */
8835 m_has_test_passed &= executeIteration(test_case);
8837 } /* for (all test cases) */
8840 if (m_has_test_passed)
8842 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8846 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8854 * @param context Rendering context.
8856 GPUShaderFP64Test7::GPUShaderFP64Test7(deqp::Context& context)
8857 : TestCase(context, "varyings", "Verifies double-precision floating-point varyings work correctly "
8858 "in all shader stages.")
8859 , m_are_double_inputs_supported(false)
8863 , m_has_test_passed(true)
8864 , m_n_max_components_per_stage(0)
8865 , m_n_xfb_varyings(0)
8874 , m_xfb_varyings(NULL)
8880 /** Compiles all shaders attached to test program object and links it.
8884 * @return true if the process was executed successfully, false otherwise.
8886 bool GPUShaderFP64Test7::buildTestProgram(_variables& variables)
8888 std::string fs_body = getFragmentShaderBody(variables);
8889 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8890 std::string gs_body = getGeometryShaderBody(variables);
8891 std::string tc_body = getTessellationControlShaderBody(variables);
8892 std::string te_body = getTessellationEvaluationShaderBody(variables);
8893 std::string vs_body = getVertexShaderBody(variables);
8894 bool result = false;
8896 /* Try to link the program object */
8897 glw::GLint link_status = GL_FALSE;
8899 /* Compile the shaders */
8900 if (!compileShader(m_fs_id, fs_body))
8902 m_testCtx.getLog() << tcu::TestLog::Message << "Fragment shader failed to compile." << tcu::TestLog::EndMessage;
8907 if (!compileShader(m_gs_id, gs_body))
8909 m_testCtx.getLog() << tcu::TestLog::Message << "Geometry shader failed to compile." << tcu::TestLog::EndMessage;
8914 if (!compileShader(m_tc_id, tc_body))
8916 m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation control shader failed to compile."
8917 << tcu::TestLog::EndMessage;
8922 if (!compileShader(m_te_id, te_body))
8924 m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation evaluation shader failed to compile."
8925 << tcu::TestLog::EndMessage;
8930 if (!compileShader(m_vs_id, vs_body))
8932 m_testCtx.getLog() << tcu::TestLog::Message << "Vertex shader failed to compile." << tcu::TestLog::EndMessage;
8938 releaseXFBVaryingNames();
8939 generateXFBVaryingNames(variables);
8941 gl.transformFeedbackVaryings(m_po_id, m_n_xfb_varyings, m_xfb_varyings, GL_INTERLEAVED_ATTRIBS);
8943 gl.linkProgram(m_po_id);
8945 /* Have we succeeded? */
8946 GLU_EXPECT_NO_ERROR(gl.getError(), "Either glTransformFeedbackVaryings() or glLinkProgram() call failed.");
8948 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
8949 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
8951 if (link_status != GL_TRUE)
8953 m_testCtx.getLog() << tcu::TestLog::Message << "A valid program object failed to link."
8954 << tcu::TestLog::EndMessage;
8959 /* Retrieve attribute locations *if* GL_ARB_vertex_attrib_64bit is supported */
8960 if (m_are_double_inputs_supported)
8962 const size_t n_variables = variables.size();
8964 for (size_t n_variable = 0; n_variable < n_variables; ++n_variable)
8966 _variable& current_variable = variables[n_variable];
8967 std::stringstream attribute_name_sstream;
8969 attribute_name_sstream << "in_vs_variable" << n_variable;
8971 if (current_variable.array_size > 1)
8973 attribute_name_sstream << "[0]";
8976 current_variable.attribute_location = gl.getAttribLocation(m_po_id, attribute_name_sstream.str().c_str());
8978 if (current_variable.attribute_location == -1)
8980 m_testCtx.getLog() << tcu::TestLog::Message << "Input double-precision attribute named ["
8981 << attribute_name_sstream.str().c_str()
8982 << "] is considered inactive which is invalid." << tcu::TestLog::EndMessage;
8984 m_has_test_passed = false;
8987 } /* for (all test variables) */
8988 } /* if (m_are_double_inputs_supported) */
8990 m_current_fs_body = fs_body;
8991 m_current_gs_body = gs_body;
8992 m_current_tc_body = tc_body;
8993 m_current_te_body = te_body;
8994 m_current_vs_body = vs_body;
9002 /** Updates shader object's body and then compiles the shader.
9004 * @param body Body to use for the shader.
9006 * @return true if the shader compiled successfully, false otherwise.
9008 bool GPUShaderFP64Test7::compileShader(glw::GLint shader_id, const std::string& body)
9010 const char* body_raw_ptr = body.c_str();
9011 glw::GLint compile_status = GL_FALSE;
9012 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9014 gl.shaderSource(shader_id, 1 /* count */, &body_raw_ptr, NULL /* length */);
9015 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
9017 gl.compileShader(shader_id);
9018 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
9020 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &compile_status);
9021 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
9023 return (compile_status == GL_TRUE);
9026 /** Configure storage of a buffer object used for capturing XFB data.
9028 * @param variables Holds descriptor for all variables used for the iteration the
9029 * BO is being configured for. Storage size will be directly related
9030 * to the number of the variables and their type.
9032 void GPUShaderFP64Test7::configureXFBBuffer(const _variables& variables)
9034 DE_ASSERT(m_n_xfb_varyings != 0);
9036 /* Geometry shaders outputs 4 vertices making up a triangle strip per draw call.
9037 * The test only draws a single patch, and triangles are caught by transform feed-back.
9038 * Let's initialize the storage, according to the list of variables that will be used
9041 unsigned int bo_size = 0;
9043 for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
9044 variables_iterator++)
9046 const _variable& variable = *variables_iterator;
9047 unsigned int n_bytes_needed = static_cast<unsigned int>(
9048 Utils::getNumberOfComponentsForVariableType(variable.type) * variable.array_size * sizeof(double));
9050 bo_size += n_bytes_needed;
9051 } /* for (all variables) */
9053 bo_size *= 3 /* vertices per triangle */ * 2; /* triangles emitted by geometry shader */
9055 /* Set up the BO storage */
9056 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9058 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
9059 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
9062 /** Deinitializes all buffers and GL objects that may have been generated
9063 * during test execution.
9065 void GPUShaderFP64Test7::deinit()
9067 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9071 gl.deleteFramebuffers(1, &m_fbo_id);
9078 gl.deleteShader(m_fs_id);
9085 gl.deleteShader(m_gs_id);
9092 gl.deleteProgram(m_po_id);
9099 gl.deleteShader(m_tc_id);
9106 gl.deleteShader(m_te_id);
9111 if (m_to_data != NULL)
9120 gl.deleteTextures(1, &m_to_id);
9125 if (m_xfb_bo_id != 0)
9127 gl.deleteBuffers(1, &m_xfb_bo_id);
9132 if (m_xfb_varyings != DE_NULL)
9134 releaseXFBVaryingNames();
9139 gl.deleteVertexArrays(1, &m_vao_id);
9146 gl.deleteShader(m_vs_id);
9152 /** Executes the functional part of the test (case a) from the test spec)
9154 * @param variables Vector of variable descriptors defining properties of
9155 * variables that should be used for the iteration.
9157 * @return true if the test passed, false otherwise.
9159 bool GPUShaderFP64Test7::executeFunctionalTest(_variables& variables)
9163 /* Build the test program */
9164 if (!buildTestProgram(variables))
9169 /* Set up input attributes if GL_ARB_vertex_attrib_64bit extension is supported */
9170 if (m_are_double_inputs_supported)
9172 setInputAttributeValues(variables);
9175 /* Set up buffer object to hold XFB data. The data will be used for logging purposes
9176 * only, if a data mismatch is detected.
9178 configureXFBBuffer(variables);
9180 /* Issue a draw call using the test program */
9181 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9183 gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f);
9184 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
9186 gl.clear(GL_COLOR_BUFFER_BIT);
9187 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
9189 gl.useProgram(m_po_id);
9190 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
9192 gl.viewport(0, /* x */
9194 m_to_width, m_to_height);
9195 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
9197 gl.beginTransformFeedback(GL_TRIANGLES);
9198 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
9200 gl.drawArrays(GL_PATCHES, 0 /* first */, 4 /* count */);
9201 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
9203 gl.endTransformFeedback();
9204 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
9206 /* Verify color attachment contents */
9207 const float epsilon = 1.0f / 255.0f;
9209 gl.readPixels(0 /* x */, 0 /* y */, m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, m_to_data);
9210 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
9212 for (unsigned int y = 0; y < m_to_height; ++y)
9214 const unsigned char* row_ptr = m_to_data + 4 /* rgba */ * m_to_width * y;
9216 for (unsigned int x = 0; x < m_to_width; ++x)
9218 const unsigned char* pixel_ptr = row_ptr + 4 /* rgba */ * x;
9220 if (de::abs(pixel_ptr[0]) > epsilon || de::abs(pixel_ptr[1] - 255) > epsilon ||
9221 de::abs(pixel_ptr[2]) > epsilon || de::abs(pixel_ptr[3]) > epsilon)
9223 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid pixel found at (" << x << ", " << y
9225 "; expected:(0, 255, 0, 0), found: ("
9226 << (int)pixel_ptr[0] << ", " << (int)pixel_ptr[1] << ", " << (int)pixel_ptr[2]
9227 << ", " << (int)pixel_ptr[3]
9228 << "), with the following variable types used as varyings:"
9229 << tcu::TestLog::EndMessage;
9231 /* List the variable types that failed the test */
9232 const size_t n_variables = variables.size();
9234 for (size_t n_variable = 0; n_variable < n_variables; ++n_variable)
9236 m_testCtx.getLog() << tcu::TestLog::Message << "gs_variable" << n_variable << ": "
9237 << Utils::getVariableTypeString(variables[n_variable].type)
9238 << " (array size:" << variables[n_variable].array_size << ")"
9239 << tcu::TestLog::EndMessage;
9240 } /* for (all variable types) */
9242 /* Log the variable contents */
9243 logVariableContents(variables);
9245 /* Log shaders used for the iteration */
9246 m_testCtx.getLog() << tcu::TestLog::Message << "Shaders used:\n"
9249 << m_current_vs_body.c_str() << "\n"
9252 << m_current_tc_body.c_str() << "\n"
9255 << m_current_te_body.c_str() << "\n"
9257 << m_current_gs_body.c_str() << "\n"
9260 << m_current_fs_body.c_str() << tcu::TestLog::EndMessage;
9266 } /* for (all columns) */
9267 } /* for (all rows) */
9274 /** Takes user-input vector of test variables and allocates & fills an array of strings
9275 * holding names of geometry shader stage varyings that should be captured during
9276 * transform feedback operation. The array will be stored in m_xfb_varyings.
9278 * @param variables Holds all test variable descriptors to be used for the iteration.
9280 void GPUShaderFP64Test7::generateXFBVaryingNames(const _variables& variables)
9282 unsigned int n_variable = 0;
9283 unsigned int n_varying = 0;
9284 unsigned int n_varyings = 0;
9286 if (m_xfb_varyings != NULL)
9288 releaseXFBVaryingNames();
9291 for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
9292 ++variables_iterator)
9294 const _variable& variable = *variables_iterator;
9296 n_varyings += variable.array_size;
9299 m_xfb_varyings = new glw::GLchar*[n_varyings];
9301 for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
9302 ++variables_iterator, ++n_variable)
9304 const _variable& variable = *variables_iterator;
9306 for (unsigned int array_index = 0; array_index < variable.array_size; ++array_index, ++n_varying)
9308 std::stringstream varying_sstream;
9309 size_t varying_length;
9311 varying_sstream << "gs_variable" << n_variable;
9313 if (variable.array_size > 1)
9315 varying_sstream << "[" << array_index << "]";
9318 /* Store the varying name */
9319 varying_length = varying_sstream.str().length();
9320 m_xfb_varyings[n_varying] = new glw::GLchar[varying_length + 1 /* terminator */];
9322 memcpy(m_xfb_varyings[n_varying], varying_sstream.str().c_str(), varying_length);
9323 m_xfb_varyings[n_varying][varying_length] = 0;
9324 } /* for (all array indices) */
9325 } /* for (all varyings) */
9327 m_n_xfb_varyings = n_varyings;
9330 /** Retrieves body of a shader that defines input variable of user-specified type & array size
9331 * without using the "flat" keyword. (case c) )
9333 * @param input_variable_type Variable type to use for input variable declaration.
9334 * @param array_size 1 if the variable should not be arrayed; otherwise defines size
9335 * of the arrayed variable.
9337 * @return Requested string.
9339 std::string GPUShaderFP64Test7::getCodeOfFragmentShaderWithNonFlatDoublePrecisionInput(
9340 Utils::_variable_type input_variable_type, unsigned int array_size)
9342 std::stringstream result_sstream;
9343 std::stringstream array_index_stringstream;
9344 std::stringstream array_size_stringstream;
9348 array_index_stringstream << "[0]";
9349 array_size_stringstream << "[" << array_size << "]";
9352 if (Utils::isMatrixVariableType(input_variable_type))
9354 array_index_stringstream << "[0].x";
9356 else if (Utils::getNumberOfComponentsForVariableType(input_variable_type) > 1)
9358 array_index_stringstream << "[0]";
9361 result_sstream << "#version 400\n"
9364 << Utils::getVariableTypeString(input_variable_type) << " test_input"
9365 << array_size_stringstream.str() << ";\n"
9367 "out float test_output;\n"
9372 << array_index_stringstream.str() << " > 2.0)\n"
9374 " test_output = 1.0;\n"
9378 " test_output = 3.0;\n"
9382 return result_sstream.str();
9385 /** Retrieves body of a shader that defines double-precision floating-point output variable. (case b) ).
9387 * @param input_variable_type Variable type to use for input variable declaration.
9388 * @param array_size 1 if the variable should not be arrayed; otherwise defines size
9389 * of the arrayed variable.
9391 * @return Requested string.
9393 std::string GPUShaderFP64Test7::getCodeOfFragmentShaderWithDoublePrecisionOutput(
9394 Utils::_variable_type output_variable_type, unsigned int array_size)
9396 std::stringstream array_index_sstream;
9397 std::stringstream array_size_sstream;
9398 std::stringstream result_sstream;
9399 std::string output_variable_type_string = Utils::getVariableTypeString(output_variable_type);
9403 array_index_sstream << "[0]";
9404 array_size_sstream << "[" << array_size << "]";
9407 result_sstream << "#version 400\n"
9410 << output_variable_type_string << " test_output" << array_size_sstream.str() << ";\n"
9415 << array_index_sstream.str() << " = " << output_variable_type_string << "(2.0);\n"
9418 return result_sstream.str();
9421 /** Retrieves body of a fragment shader that uses user-specified set of variables
9422 * to declare contents of input & output block.
9424 * @param variables As per description.
9426 * @return Requested string.
9428 std::string GPUShaderFP64Test7::getFragmentShaderBody(const _variables& variables)
9430 std::stringstream result_sstream;
9432 /* Form the pre-amble */
9433 result_sstream << "#version 400\n"
9436 /* Add input block */
9439 << getVariableDeclarations("gs", variables, "flat") << "};\n"
9442 /* Add output variable */
9443 << "out vec4 result;\n"
9446 /* Add main() definition */
9449 "const double epsilon = 1e-5;\n"
9451 "result = vec4(1, 0, 0, 0);\n"
9454 /* Determine expected values first */
9455 unsigned int base_counter = 1;
9456 const size_t n_variables = variables.size();
9458 for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
9460 unsigned int variable_array_size = variables[n_variable].array_size;
9461 Utils::_variable_type variable_type = variables[n_variable].type;
9462 unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
9463 std::string variable_type_string = Utils::getVariableTypeString(variable_type);
9465 std::stringstream array_size_sstream;
9467 if (variable_array_size > 1)
9469 array_size_sstream << "[" << variable_array_size << "]";
9472 /* Local variable declaration */
9473 result_sstream << variable_type_string << " expected_variable" << n_variable << array_size_sstream.str()
9477 /* Set expected values */
9478 for (unsigned int index = 0; index < variable_array_size; ++index)
9480 std::stringstream array_index_sstream;
9482 if (variable_array_size > 1)
9484 array_index_sstream << "[" << index << "]";
9487 result_sstream << "expected_variable" << n_variable << array_index_sstream.str() << " = "
9488 << variable_type_string << "(";
9490 for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
9492 unsigned int expected_value =
9493 (base_counter + 0) + (base_counter + 1) + (base_counter + 2) + (base_counter + 3);
9495 if (m_are_double_inputs_supported)
9497 /* VS input attributes */
9498 //expected_value += (base_counter + 6);
9499 expected_value -= 1;
9502 result_sstream << expected_value;
9504 if (n_component != (n_variable_type_components - 1))
9506 result_sstream << ", ";
9510 } /* for (all components) */
9512 result_sstream << ");\n";
9513 } /* for (all array indices) */
9515 result_sstream << "\n";
9516 } /* for (all variable types) */
9518 /* Now that we know the expected values, do a huge conditional check to verify if all
9519 * input variables carry correct information.
9521 result_sstream << "if (";
9523 for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
9525 unsigned int variable_array_size = variables[n_variable].array_size;
9526 Utils::_variable_type variable_type = variables[n_variable].type;
9527 bool is_variable_type_matrix = Utils::isMatrixVariableType(variable_type);
9528 unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
9529 std::string variable_type_string = Utils::getVariableTypeString(variable_type);
9531 for (unsigned int index = 0; index < variable_array_size; ++index)
9533 std::stringstream array_index_sstream;
9535 if (variable_array_size > 1)
9537 array_index_sstream << "[" << index << "]";
9540 for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
9542 std::stringstream component_index_sstream;
9544 if (n_variable_type_components > 1)
9546 component_index_sstream << "[" << n_component << "]";
9549 result_sstream << "abs(expected_variable" << n_variable << array_index_sstream.str();
9551 if (is_variable_type_matrix)
9553 const unsigned int n_columns = Utils::getNumberOfColumnsForVariableType(variable_type);
9554 const unsigned int column = n_component % n_columns;
9555 const unsigned int row = n_component / n_columns;
9557 result_sstream << "[" << column << "]"
9559 << Utils::getComponentAtIndex(row);
9563 result_sstream << component_index_sstream.str();
9566 result_sstream << " - gs_variable" << n_variable << array_index_sstream.str();
9568 if (is_variable_type_matrix)
9570 const unsigned int n_columns = Utils::getNumberOfColumnsForVariableType(variable_type);
9571 const unsigned int column = n_component % n_columns;
9572 const unsigned int row = n_component / n_columns;
9574 result_sstream << "[" << column << "]"
9576 << Utils::getComponentAtIndex(row);
9580 result_sstream << component_index_sstream.str();
9583 result_sstream << ") <= epsilon &&";
9584 } /* for (all components) */
9585 } /* for (all array indices) */
9586 } /* for (all variable types) */
9588 result_sstream << "true)\n"
9590 " result = vec4(0, 1, 0, 0);\n"
9595 return result_sstream.str();
9598 /** Retrieves body of a geometry shader that uses user-specified set of variables
9599 * to declare contents of input & output block.
9601 * @param variables As per description.
9603 * @return Requested string.
9605 std::string GPUShaderFP64Test7::getGeometryShaderBody(const _variables& variables)
9607 std::stringstream result_sstream;
9609 /* Form the pre-amble */
9610 result_sstream << "#version 400\n"
9612 "layout(triangles) in;\n"
9613 "layout(triangle_strip, max_vertices=4) out;\n"
9616 /* Add the input block */
9619 << getVariableDeclarations("te", variables) << "} in_data[];\n"
9622 /* Add the output block */
9625 << getVariableDeclarations("gs", variables, "flat") << "};\n"
9628 /* Declare main() function */
9632 /* Take input variables, add a predefined value and forward them to output variables */
9633 const float quad_vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
9634 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };
9635 const unsigned int n_quad_vertices =
9636 sizeof(quad_vertices) / sizeof(quad_vertices[0]) / 4 /* components per vertex */;
9637 const size_t n_variables = variables.size();
9639 for (unsigned int n_quad_vertex = 0; n_quad_vertex < n_quad_vertices; ++n_quad_vertex)
9641 unsigned int counter = 4;
9642 const float* current_quad_vertex = quad_vertices + n_quad_vertex * 4 /* components per vertex */;
9644 for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
9646 unsigned int variable_array_size = variables[n_variable].array_size;
9647 Utils::_variable_type variable_type = variables[n_variable].type;
9648 unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
9649 std::string variable_type_string = Utils::getVariableTypeString(variable_type);
9651 for (unsigned int index = 0; index < variable_array_size; ++index)
9653 std::stringstream array_index_sstream;
9655 if (variable_array_size > 1)
9657 array_index_sstream << "[" << index << "]";
9660 result_sstream << "gs_variable" << n_variable << array_index_sstream.str()
9661 << " = in_data[0].te_variable" << n_variable << array_index_sstream.str() << " + "
9662 << variable_type_string << "(";
9664 for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
9666 result_sstream << (counter++);
9668 if (n_component != (n_variable_type_components - 1))
9670 result_sstream << ", ";
9672 } /* for (all components) */
9674 result_sstream << ");\n";
9675 } /* for (all array indices) */
9676 } /* for (all variable types) */
9678 result_sstream << "gl_Position = vec4(" << current_quad_vertex[0] << ", " << current_quad_vertex[1] << ", "
9679 << current_quad_vertex[2] << ", " << current_quad_vertex[3] << ");\n"
9681 } /* for (all emitted quad vertices) */
9683 result_sstream << "EndPrimitive();\n"
9687 return result_sstream.str();
9690 /** Retrieves body of a tessellation control shader that uses user-specified set of variables
9691 * to declare contents of input & output block.
9693 * @param variables As per description.
9695 * @return Requested string.
9697 std::string GPUShaderFP64Test7::getTessellationControlShaderBody(const _variables& variables)
9699 std::stringstream result_sstream;
9701 /* Form the pre-amble */
9702 result_sstream << "#version 400\n"
9704 "layout (vertices=4) out;\n"
9706 /* Declare input block */
9709 << getVariableDeclarations("vs", variables) << "} in_data[];\n"
9711 /* Declare output block */
9714 << getVariableDeclarations("tc", variables) << "} out_data[];\n"
9720 " gl_TessLevelInner[0] = 1;\n"
9721 " gl_TessLevelInner[1] = 1;\n"
9722 " gl_TessLevelOuter[0] = 1;\n"
9723 " gl_TessLevelOuter[1] = 1;\n"
9724 " gl_TessLevelOuter[2] = 1;\n"
9725 " gl_TessLevelOuter[3] = 1;\n"
9728 /* Take input variables, add a predefined value and forward them to output variables */
9729 const size_t n_variables = variables.size();
9730 unsigned int counter = 2;
9732 for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
9734 unsigned int variable_array_size = variables[n_variable].array_size;
9735 Utils::_variable_type variable_type = variables[n_variable].type;
9736 unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
9737 std::string variable_type_string = Utils::getVariableTypeString(variable_type);
9739 for (unsigned int index = 0; index < variable_array_size; ++index)
9741 std::stringstream array_index_sstream;
9743 if (variable_array_size > 1)
9745 array_index_sstream << "[" << index << "]";
9748 result_sstream << "out_data[gl_InvocationID].tc_variable" << n_variable << array_index_sstream.str()
9749 << " = in_data[0].vs_variable" << n_variable << array_index_sstream.str() << " + "
9750 << variable_type_string << "(";
9752 for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
9754 result_sstream << (counter++);
9756 if (n_component != (n_variable_type_components - 1))
9758 result_sstream << ", ";
9762 result_sstream << ");\n";
9763 } /* for (all array indices) */
9764 } /* for (all variable types) */
9766 result_sstream << "}\n";
9769 return result_sstream.str();
9772 /** Retrieves body of a tessellation evaluation shader that uses user-specified set of variables
9773 * to declare contents of input & output block.
9775 * @param variables As per description.
9777 * @return Requested string.
9779 std::string GPUShaderFP64Test7::getTessellationEvaluationShaderBody(const _variables& variables)
9781 std::stringstream result_sstream;
9783 /* Form the pre-amble */
9784 result_sstream << "#version 400\n"
9786 "layout(quads) in;\n"
9789 /* Define input block */
9792 << getVariableDeclarations("tc", variables) << "} in_data[];\n"
9795 /* Define output block */
9798 << getVariableDeclarations("te", variables) << "};\n"
9805 /* Take input variables, add a predefined value and forward them to output variables */
9806 const size_t n_variables = variables.size();
9807 unsigned int counter = 3;
9809 for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
9811 unsigned int variable_array_size = variables[n_variable].array_size;
9812 Utils::_variable_type variable_type = variables[n_variable].type;
9813 unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
9814 std::string variable_type_string = Utils::getVariableTypeString(variable_type);
9816 for (unsigned int index = 0; index < variable_array_size; ++index)
9818 std::stringstream array_index_sstream;
9820 if (variable_array_size > 1)
9822 array_index_sstream << "[" << index << "]";
9825 result_sstream << "te_variable" << n_variable << array_index_sstream.str() << " = in_data[0].tc_variable"
9826 << n_variable << array_index_sstream.str() << " + " << variable_type_string << "(";
9828 for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
9830 result_sstream << (counter++);
9832 if (n_component != (n_variable_type_components - 1))
9834 result_sstream << ", ";
9836 } /* for (all components) */
9838 result_sstream << ");\n";
9839 } /* for (all array indices) */
9840 } /* for (all variable types) */
9842 result_sstream << "}\n";
9845 return result_sstream.str();
9848 /** Returns a string containing declarations of user-specified set of variables.
9849 * Each declaration can optionally use a layot qualifier requested by the caller.
9851 * @param prefix Prefix to use for variable names.
9852 * @param variables List of variables to declare in the result string.
9853 * @param explicit_locations true if each declaration should explicitly define location
9854 * of the variable ( eg. (layout location=X) )
9855 * @param layout_qualifier Optional qualifier to use for the declaration. Must not
9858 * @return Requested string.
9860 std::string GPUShaderFP64Test7::getVariableDeclarations(const char* prefix, const _variables& variables,
9861 const char* layout_qualifier)
9863 std::stringstream result_sstream;
9865 /* Define output variables */
9866 const size_t n_variables = variables.size();
9868 for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
9870 unsigned int variable_array_size = variables[n_variable].array_size;
9871 Utils::_variable_type variable_type = variables[n_variable].type;
9872 std::string variable_type_string = Utils::getVariableTypeString(variable_type);
9874 result_sstream << layout_qualifier << " " << variable_type_string << " " << prefix << "_variable" << n_variable;
9876 if (variable_array_size > 1)
9878 result_sstream << "[" << variable_array_size << "]";
9881 result_sstream << ";\n";
9882 } /* for (all user-specified variable types) */
9884 return result_sstream.str();
9887 /** Retrieves body of a vertex shader that uses user-specified set of variables
9888 * to declare contents of input & output block.
9890 * @param variables As per description.
9892 * @return Requested string.
9894 std::string GPUShaderFP64Test7::getVertexShaderBody(const _variables& variables)
9896 std::stringstream result_sstream;
9898 /* Form pre-amble */
9899 result_sstream << "#version 400\n"
9902 /* Define input variables if GL_ARB_vertex_attrib_64bit is supported */
9903 if (m_are_double_inputs_supported)
9905 result_sstream << "#extension GL_ARB_vertex_attrib_64bit : require\n"
9906 << getVariableDeclarations("in_vs", variables, "in");
9909 /* Define output variables */
9910 result_sstream << "out VS_DATA\n"
9912 << getVariableDeclarations("vs", variables);
9915 result_sstream << "};\n"
9920 /* Set output variable values */
9921 unsigned int counter = 1;
9922 const size_t n_variables = variables.size();
9924 for (unsigned int n_variable = 0; n_variable < n_variables; ++n_variable)
9926 unsigned int variable_array_size = variables[n_variable].array_size;
9927 Utils::_variable_type variable_type = variables[n_variable].type;
9928 const unsigned int n_variable_type_components = Utils::getNumberOfComponentsForVariableType(variable_type);
9929 std::string variable_type_string = Utils::getVariableTypeString(variable_type);
9931 for (unsigned int index = 0; index < variable_array_size; ++index)
9933 if (variable_array_size == 1)
9935 result_sstream << "vs_variable" << n_variable << " = " << variable_type_string << "(";
9939 result_sstream << "vs_variable" << n_variable << "[" << index << "]"
9940 << " = " << variable_type_string << "(";
9943 for (unsigned int n_component = 0; n_component < n_variable_type_components; ++n_component)
9945 result_sstream << (double)(counter++);
9947 /* Use input attributes, if available */
9948 if (m_are_double_inputs_supported)
9950 result_sstream << " + in_vs_variable" << n_variable;
9952 if (variable_array_size > 1)
9954 result_sstream << "[" << index << "]";
9957 if (Utils::isMatrixVariableType(variables[n_variable].type))
9959 const unsigned int n_columns = Utils::getNumberOfColumnsForVariableType(variable_type);
9960 const unsigned int column = n_component % n_columns;
9961 const unsigned int row = n_component / n_columns;
9963 result_sstream << "[" << (column) << "]"
9965 << Utils::getComponentAtIndex(row);
9967 else if (n_variable_type_components > 1)
9969 result_sstream << "[" << n_component << "]";
9973 if (n_component != (n_variable_type_components - 1))
9975 result_sstream << ", ";
9977 } /* for (all components) */
9979 result_sstream << ");\n";
9981 } /* for (all variable types) */
9983 /* We will be using geometry shader to lay out the actual vertices so
9984 * the only thing we need to make sure is that the vertex never gets
9987 result_sstream << "gl_Position = vec4(0, 0, 0, 1);\n"
9991 return result_sstream.str();
9994 /** Initializes shader objects required to run the test. */
9995 void GPUShaderFP64Test7::initTest()
9997 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9999 /* Are double-precision input variables supported? */
10000 m_are_double_inputs_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit");
10002 /* Create a vertex array object */
10003 gl.genVertexArrays(1, &m_vao_id);
10004 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
10006 gl.bindVertexArray(m_vao_id);
10007 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
10009 /* Create a texture object we will use as FBO's color attachment */
10010 gl.genTextures(1, &m_to_id);
10011 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
10013 gl.bindTexture(GL_TEXTURE_2D, m_to_id);
10014 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
10016 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, m_to_width, m_to_height);
10017 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
10019 /* Allocate temporary buffer to hold the texture data we will be reading
10020 * from color attachment. */
10021 m_to_data = new unsigned char[m_to_width * m_to_height * 4 /* RGBA */];
10023 /* Create and set up a framebuffer object */
10024 gl.genFramebuffers(1, &m_fbo_id);
10025 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
10027 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
10028 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindframebuffer() call failed.");
10030 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0 /* level */);
10031 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
10033 /* Create all shader objects */
10034 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
10035 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
10036 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
10037 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
10038 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
10039 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
10041 /* Create test program object */
10042 m_po_id = gl.createProgram();
10043 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
10045 /* Attach the shaders to the program object */
10046 gl.attachShader(m_po_id, m_fs_id);
10047 gl.attachShader(m_po_id, m_gs_id);
10048 gl.attachShader(m_po_id, m_tc_id);
10049 gl.attachShader(m_po_id, m_te_id);
10050 gl.attachShader(m_po_id, m_vs_id);
10051 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
10053 /* The test passes double-precision values through the whole rendering pipeline.
10054 * This translates to a notable amount of components that we would need to transfer
10055 * all values in one fell swoop. The number is large enough to exceed minimum
10056 * capabilities as described for OpenGL 4.0 implementations.
10057 * For that reason, the test executes in turns. Each turn is allocated as many
10058 * double-precision scalar/matrix values as supported by the tested GL implementation.
10060 glw::GLint gl_max_fragment_input_components_value = 0;
10061 glw::GLint gl_max_geometry_input_components_value = 0;
10062 glw::GLint gl_max_geometry_output_components_value = 0;
10063 glw::GLint gl_max_tess_control_input_components_value = 0;
10064 glw::GLint gl_max_tess_control_output_components_value = 0;
10065 glw::GLint gl_max_tess_evaluation_input_components_value = 0;
10066 glw::GLint gl_max_tess_evaluation_output_components_value = 0;
10067 glw::GLint gl_max_transform_feedback_interleaved_components_value = 0;
10068 glw::GLint gl_max_vertex_output_components_value = 0;
10070 gl.getIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &gl_max_fragment_input_components_value);
10071 gl.getIntegerv(GL_MAX_GEOMETRY_INPUT_COMPONENTS, &gl_max_geometry_input_components_value);
10072 gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &gl_max_geometry_output_components_value);
10073 gl.getIntegerv(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, &gl_max_tess_control_input_components_value);
10074 gl.getIntegerv(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, &gl_max_tess_control_output_components_value);
10075 gl.getIntegerv(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, &gl_max_tess_evaluation_input_components_value);
10076 gl.getIntegerv(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, &gl_max_tess_evaluation_output_components_value);
10077 gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
10078 &gl_max_transform_feedback_interleaved_components_value);
10079 gl.getIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &gl_max_vertex_output_components_value);
10080 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetintegerv() call(s) failed.");
10082 m_n_max_components_per_stage =
10083 de::min(gl_max_vertex_output_components_value, gl_max_tess_control_input_components_value);
10084 m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_fragment_input_components_value);
10085 m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_geometry_input_components_value);
10086 m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_geometry_output_components_value);
10087 m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_tess_control_output_components_value);
10088 m_n_max_components_per_stage = de::min(m_n_max_components_per_stage, gl_max_tess_evaluation_input_components_value);
10089 m_n_max_components_per_stage =
10090 de::min(m_n_max_components_per_stage, gl_max_tess_evaluation_output_components_value);
10091 m_n_max_components_per_stage =
10092 de::min(m_n_max_components_per_stage, gl_max_transform_feedback_interleaved_components_value);
10094 /* Update GL_PATCH_VERTICES setting so that we only use a single vertex to build
10095 * the input patch */
10096 gl.patchParameteri(GL_PATCH_VERTICES, 1);
10098 GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");
10100 /* Initialize a BO we will use to hold XFB data */
10101 gl.genBuffers(1, &m_xfb_bo_id);
10102 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
10104 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
10105 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
10107 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
10108 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
10111 /** Executes test iteration.
10113 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
10115 tcu::TestNode::IterateResult GPUShaderFP64Test7::iterate()
10117 /* Do not execute the test if GL_ARB_texture_view is not supported */
10118 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
10120 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
10123 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_vertex_attrib_64bit"))
10125 throw tcu::NotSupportedError("GL_ARB_vertex_attrib_64bit is not supported.");
10128 /* Initialize GL objects required to run the test */
10131 /* Check the negative cases first */
10132 const Utils::_variable_type double_variable_types[] = {
10133 Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_DVEC2, Utils::VARIABLE_TYPE_DVEC3,
10134 Utils::VARIABLE_TYPE_DVEC4, Utils::VARIABLE_TYPE_DMAT2, Utils::VARIABLE_TYPE_DMAT2X3,
10135 Utils::VARIABLE_TYPE_DMAT2X4, Utils::VARIABLE_TYPE_DMAT3, Utils::VARIABLE_TYPE_DMAT3X2,
10136 Utils::VARIABLE_TYPE_DMAT3X4, Utils::VARIABLE_TYPE_DMAT4, Utils::VARIABLE_TYPE_DMAT4X2,
10137 Utils::VARIABLE_TYPE_DMAT4X3,
10139 const unsigned int n_double_variable_types = sizeof(double_variable_types) / sizeof(double_variable_types[0]);
10141 for (unsigned int n_double_variable_type = 0; n_double_variable_type < n_double_variable_types;
10142 ++n_double_variable_type)
10144 for (unsigned int array_size = 1; array_size < 3; ++array_size)
10146 Utils::_variable_type variable_type = double_variable_types[n_double_variable_type];
10148 if (compileShader(m_fs_id, getCodeOfFragmentShaderWithDoublePrecisionOutput(variable_type, array_size)))
10150 m_testCtx.getLog() << tcu::TestLog::Message
10151 << "A fragment shader with double-precision output variable compiled successfully."
10152 << tcu::TestLog::EndMessage;
10154 m_has_test_passed = false;
10157 if (compileShader(m_fs_id,
10158 getCodeOfFragmentShaderWithNonFlatDoublePrecisionInput(variable_type, array_size)))
10161 << tcu::TestLog::Message
10162 << "A fragment shader with double-precision input variables lacking flat layout qualifier"
10163 " compiled successfully."
10164 << tcu::TestLog::EndMessage;
10166 m_has_test_passed = false;
10169 } /* for (all variable types) */
10171 /* Execute functional test. Split the run into as many iterations as necessary
10172 * so that we do not exceed GL implementation's capabilities. */
10173 unsigned int n_tested_variables = 0;
10174 _variables variables_to_test;
10176 while (n_tested_variables != n_double_variable_types * 2 /* arrayed & non-arrayed */)
10178 glw::GLint total_n_used_components = 0;
10180 /* Use as many variables as possible for the iterations. Do not exceed maximum amount
10181 * of varying components that can be used for all shadr stages.
10183 while (total_n_used_components < m_n_max_components_per_stage &&
10184 n_tested_variables != n_double_variable_types * 2 /* arrayed & non-arrayed */)
10186 _variable new_variable;
10187 unsigned int n_type_components = 0;
10188 glw::GLint n_used_components = 0;
10190 new_variable.array_size =
10191 ((n_tested_variables % 2) == 0) ? 1 /* non-arrayed variable */ : 2; /* arrayed variable */
10192 new_variable.type = double_variable_types[n_tested_variables / 2];
10194 /* Double-precision varyings can use twice as many components as single-precision FPs */
10195 n_type_components = 4 /* components per location */ *
10196 Utils::getNumberOfLocationsUsedByDoublePrecisionVariableType(new_variable.type);
10197 n_used_components = n_type_components * new_variable.array_size * 2;
10199 /* Do we have enough space? */
10200 if (total_n_used_components + n_used_components > m_n_max_components_per_stage)
10202 if (n_used_components > m_n_max_components_per_stage)
10203 { //if the number of components for this variable is larger than the max_components_per_stage, then skip it.
10204 n_tested_variables++;
10209 /* We can safely test the type in current iteration */
10210 total_n_used_components += n_used_components;
10211 n_tested_variables++;
10213 variables_to_test.push_back(new_variable);
10216 if (variables_to_test.size() > 0)
10218 m_has_test_passed &= executeFunctionalTest(variables_to_test);
10220 variables_to_test.clear();
10225 if (m_has_test_passed)
10227 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
10231 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
10237 /** Logs contents of test variables, as XFBed out by already executed test iteration. */
10238 void GPUShaderFP64Test7::logVariableContents(const _variables& variables)
10240 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10241 std::stringstream log_sstream;
10243 log_sstream << "Test variable values as retrieved from geometry shader:\n";
10245 /* Map the XFB BO contents into process space */
10246 const void* xfb_bo_data = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
10248 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
10250 /* Read the variable contents. We only care about the set of varyings emitted
10251 * for first vertex in the geometry shader */
10252 unsigned int n_varying = 0;
10253 const unsigned char* traveller_ptr = (const unsigned char*)xfb_bo_data;
10255 for (_variables_const_iterator variables_iterator = variables.begin(); variables_iterator != variables.end();
10256 ++variables_iterator, ++n_varying)
10258 const _variable& variable = *variables_iterator;
10259 const Utils::_variable_type& base_variable_type = Utils::getBaseVariableType(variable.type);
10260 const unsigned int n_components = Utils::getNumberOfComponentsForVariableType(variable.type);
10262 for (unsigned int array_index = 0; array_index < variable.array_size; ++array_index)
10264 log_sstream << "gs_variable" << n_varying;
10266 if (variable.array_size > 1)
10268 log_sstream << "[" << array_index << "]";
10271 log_sstream << ": (";
10273 for (unsigned int n_component = 0; n_component < n_components; ++n_component)
10275 log_sstream << Utils::getStringForVariableTypeValue(base_variable_type, traveller_ptr);
10277 if (n_component != (n_components - 1))
10279 log_sstream << ", ";
10282 traveller_ptr += sizeof(double);
10285 log_sstream << ")\n";
10286 } /* for (all array indices) */
10287 } /* for (all variables) */
10290 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
10291 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
10293 /* Pass the logged stream into the framework */
10294 m_testCtx.getLog() << tcu::TestLog::Message << log_sstream.str().c_str() << tcu::TestLog::EndMessage;
10297 /** De-allocates an arary holding strings representing names of varyings that
10298 * should be used for transform feed-back.
10300 void GPUShaderFP64Test7::releaseXFBVaryingNames()
10302 for (unsigned int n_varying = 0; n_varying < m_n_xfb_varyings; ++n_varying)
10304 delete[] m_xfb_varyings[n_varying];
10307 delete m_xfb_varyings;
10308 m_xfb_varyings = DE_NULL;
10310 m_n_xfb_varyings = 0;
10313 /** This function should only be called if GL_ARB_vertex_attrib_64bit extension is supported.
10314 * Takes a list of test variables used for current iteration and assigns increasing values
10315 * to subsequent input attributes of the test program.
10317 * @param variables Test variables of the current iteration.
10319 void GPUShaderFP64Test7::setInputAttributeValues(const _variables& variables)
10321 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10322 unsigned int counter = 6;
10324 for (_variables_const_iterator variable_iterator = variables.begin(); variable_iterator != variables.end();
10325 variable_iterator++)
10327 const _variable& variable = *variable_iterator;
10328 const bool is_matrix_type = Utils::isMatrixVariableType(variable.type);
10329 const unsigned int n_total_components = Utils::getNumberOfComponentsForVariableType(variable.type);
10330 unsigned int n_components = 0;
10331 unsigned int n_columns = 1;
10333 if (is_matrix_type)
10335 n_columns = Utils::getNumberOfColumnsForVariableType(variable.type);
10336 n_components = n_total_components / n_columns;
10338 DE_ASSERT(n_total_components % n_columns == 0);
10342 n_components = n_total_components;
10345 DE_ASSERT(n_components >= 1 && n_components <= 4);
10347 for (unsigned int index = 0; index < n_columns * variable.array_size; ++index)
10349 const double data[] = { -1, -1, -1, -1 };
10351 switch (n_components)
10355 gl.vertexAttribL1dv(variable.attribute_location + index, data);
10356 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib1dv() call failed.");
10363 gl.vertexAttribL2dv(variable.attribute_location + index, data);
10364 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib2dv() call failed.");
10371 gl.vertexAttribL3dv(variable.attribute_location + index, data);
10372 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib3dv() call failed.");
10379 gl.vertexAttribL4dv(variable.attribute_location + index, data);
10380 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttrib4dv() call failed.");
10387 TCU_FAIL("Unrecognized number of components");
10389 } /* switch (n_components) */
10391 /* Make sure VAAs are disabled */
10392 gl.disableVertexAttribArray(variable.attribute_location + index);
10393 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray() call failed.");
10395 counter += n_components;
10396 } /* for (all array indices) */
10397 } /* for (all variables) */
10402 * @param context Rendering context.
10404 GPUShaderFP64Test8::GPUShaderFP64Test8(deqp::Context& context)
10405 : TestCase(context, "valid_constructors", "Verifies that valid double-precision floating-point constructors "
10406 "are accepted during compilation stage")
10413 , m_has_test_passed(true)
10417 /** Deinitializes all buffers and GL objects that may have been generated
10418 * during test execution.
10420 void GPUShaderFP64Test8::deinit()
10422 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10426 gl.deleteShader(m_cs_id);
10433 gl.deleteShader(m_fs_id);
10440 gl.deleteShader(m_gs_id);
10447 gl.deleteShader(m_tc_id);
10454 gl.deleteShader(m_te_id);
10461 gl.deleteShader(m_vs_id);
10467 /** Executes a single test case.
10469 * This function can throw TestError exceptions if GL implementation reports
10472 * @param test_case Test case descriptor.
10474 * @return true if test case passed, false otherwise.
10476 bool GPUShaderFP64Test8::executeIteration(const _test_case& test_case)
10478 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10479 const glw::GLuint so_ids[] = { m_cs_id, m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
10480 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
10481 bool result = true;
10482 const char* stage_body = NULL;
10483 const char* stage_name = NULL;
10485 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
10487 const glw::GLuint so_id = so_ids[n_so_id];
10489 /* Skip compute shader if it is not supported */
10495 /* Compile the shader */
10496 gl.compileShader(so_id);
10497 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
10499 /* Has the compilation succeeded as expected? */
10500 glw::GLint compile_status = GL_FALSE;
10502 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
10503 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
10505 if (compile_status == GL_FALSE)
10507 /* What is the current stage's name? */
10508 if (so_id == m_cs_id)
10510 stage_body = test_case.cs_shader_body.c_str();
10511 stage_name = "Compute shader";
10513 else if (so_id == m_fs_id)
10515 stage_body = test_case.fs_shader_body.c_str();
10516 stage_name = "Fragment shader";
10518 else if (so_id == m_gs_id)
10520 stage_body = test_case.gs_shader_body.c_str();
10521 stage_name = "Geometry shader";
10523 else if (so_id == m_tc_id)
10525 stage_body = test_case.tc_shader_body.c_str();
10526 stage_name = "Tessellation control shader";
10528 else if (so_id == m_te_id)
10530 stage_body = test_case.te_shader_body.c_str();
10531 stage_name = "Tessellation evaluation shader";
10533 else if (so_id == m_vs_id)
10535 stage_body = test_case.vs_shader_body.c_str();
10536 stage_name = "Vertex shader";
10540 /* Doesn't make much sense to throw exceptions here so.. */
10542 stage_name = "[?]";
10545 /* This shader should have never failed to compile! */
10546 m_testCtx.getLog() << tcu::TestLog::Message << stage_name
10547 << " has not compiled successfully, even though the shader is valid."
10548 " Following is shader's body:\n"
10549 << stage_body << tcu::TestLog::EndMessage;
10553 } /* for (all shader objects) */
10558 /** Retrieves all argument lists that can be used to initialize a variable of user-specified
10561 * @param variable_type Variable type to return valid argument lists for.
10563 GPUShaderFP64Test8::_argument_lists GPUShaderFP64Test8::getArgumentListsForVariableType(
10564 const Utils::_variable_type& variable_type)
10566 const Utils::_variable_type matrix_types[] = {
10567 Utils::VARIABLE_TYPE_DMAT2, Utils::VARIABLE_TYPE_DMAT2X3, Utils::VARIABLE_TYPE_DMAT2X4,
10568 Utils::VARIABLE_TYPE_DMAT3, Utils::VARIABLE_TYPE_DMAT3X2, Utils::VARIABLE_TYPE_DMAT3X4,
10569 Utils::VARIABLE_TYPE_DMAT4, Utils::VARIABLE_TYPE_DMAT4X2, Utils::VARIABLE_TYPE_DMAT4X3,
10571 const Utils::_variable_type scalar_types[] = { Utils::VARIABLE_TYPE_DOUBLE, Utils::VARIABLE_TYPE_DVEC2,
10572 Utils::VARIABLE_TYPE_DVEC3, Utils::VARIABLE_TYPE_DVEC4 };
10573 const unsigned int n_matrix_types = sizeof(matrix_types) / sizeof(matrix_types[0]);
10574 const unsigned int n_scalar_types = sizeof(scalar_types) / sizeof(scalar_types[0]);
10575 const int n_total_components = (int)Utils::getNumberOfComponentsForVariableType(variable_type);
10577 /* Construct the argument list tree root. Each node carries a counter that tells how many components
10578 * have already been assigned. Nodes that eat up all components are considered leaves and do not have
10579 * any children. Otherwise, each node is assigned as many children, as there are types that could be
10580 * used to define a subsequent argument, and its counter is increased by the amount of components
10581 * described by the type.
10583 _argument_list_tree_node root;
10585 root.n_components_used = 0;
10586 root.parent = NULL;
10587 root.type = variable_type;
10589 /* Fill till all leaves use up all available components */
10590 _argument_list_tree_node_queue nodes_queue;
10592 nodes_queue.push(&root);
10596 /* Pop the first item in the queue */
10597 _argument_list_tree_node* current_node_ptr = nodes_queue.front();
10600 /* Matrix variable types can be defined by a combination of non-matrix variable types OR
10601 * a single matrix variable type.
10603 * Let's handle the latter case first.
10605 const int n_components_remaining = n_total_components - current_node_ptr->n_components_used;
10607 if (Utils::isMatrixVariableType(current_node_ptr->type))
10609 /* Iterate through all known matrix types. All the types can be used
10610 * as a constructor, assuming only one value is used to define new matrix's
10612 for (unsigned int n_matrix_type = 0; n_matrix_type < n_matrix_types; ++n_matrix_type)
10614 Utils::_variable_type new_argument_type = matrix_types[n_matrix_type];
10616 /* Construct a new child node. Since GLSL spec clearly states we must not use more
10617 * than one constructor argument if the only argument is a matrix type, mark the node
10618 * as if it defined all available components.
10620 _argument_list_tree_node* new_subnode = new _argument_list_tree_node;
10622 new_subnode->n_components_used = n_total_components;
10623 new_subnode->parent = current_node_ptr;
10624 new_subnode->type = new_argument_type;
10626 /* Add the descriptor to node list but do not add it to the queue. This would be
10627 * a redundant operation, since no new children nodes would have been assigned to
10628 * this node anyway.
10630 current_node_ptr->children.push_back(new_subnode);
10631 } /* for (all matrix types) */
10632 } /* if (current node's type is a matrix) */
10634 /* Now for a combination of non-matrix variable types.. */
10635 if (!Utils::isMatrixVariableType(current_node_ptr->type))
10637 /* Iterate through all known scalar types */
10638 for (unsigned int n_scalar_type = 0; n_scalar_type < n_scalar_types; ++n_scalar_type)
10640 Utils::_variable_type new_argument_type = scalar_types[n_scalar_type];
10641 const int n_new_argument_components = Utils::getNumberOfComponentsForVariableType(new_argument_type);
10643 /* Only use the scalar type if we don't exceed the amount of components we can define
10644 * for requested type.
10646 if (n_new_argument_components <= n_components_remaining)
10648 /* Form new node descriptor */
10649 _argument_list_tree_node* new_subnode = new _argument_list_tree_node;
10651 new_subnode->n_components_used = n_new_argument_components + current_node_ptr->n_components_used;
10652 new_subnode->parent = current_node_ptr;
10653 new_subnode->type = new_argument_type;
10655 current_node_ptr->children.push_back(new_subnode);
10656 nodes_queue.push(new_subnode);
10658 } /* for (all scalar types) */
10659 } /* if (!Utils::isMatrixVariableType(current_node_ptr->type) ) */
10660 } while (nodes_queue.size() > 0);
10662 /* To construct the argument lists, traverse the tree. Each path from root to child
10663 * gives us a single argument list.
10665 * First, identify leaf nodes.
10667 _argument_list_tree_nodes leaf_nodes;
10669 nodes_queue.push(&root);
10673 _argument_list_tree_node* current_node_ptr = nodes_queue.front();
10676 if (current_node_ptr->children.size() == 0)
10678 /* This is a leaf node !*/
10679 leaf_nodes.push_back(current_node_ptr);
10683 /* Throw all children nodes to the queue */
10684 const unsigned int n_children_nodes = (const unsigned int)current_node_ptr->children.size();
10686 for (unsigned int n_children_node = 0; n_children_node < n_children_nodes; ++n_children_node)
10688 nodes_queue.push(current_node_ptr->children[n_children_node]);
10689 } /* for (all children nodes) */
10691 } while (nodes_queue.size() > 0);
10693 /* For all leaf nodes, move up the tree and construct the argument lists. */
10694 const unsigned int n_leaf_nodes = (const unsigned int)leaf_nodes.size();
10695 _argument_lists result;
10697 for (unsigned int n_leaf_node = 0; n_leaf_node < n_leaf_nodes; ++n_leaf_node)
10699 _argument_list argument_list;
10700 _argument_list_tree_node* current_node_ptr = leaf_nodes[n_leaf_node];
10704 if (current_node_ptr != &root)
10706 if (argument_list.size() == 0)
10708 argument_list.push_back(current_node_ptr->type);
10712 argument_list.insert(argument_list.begin(), current_node_ptr->type);
10716 current_node_ptr = current_node_ptr->parent;
10717 } while (current_node_ptr != NULL);
10719 result.push_back(argument_list);
10720 } /* for (all leaf nodes) */
10725 /** Retrieves body of a compute shader that should be used for the purpose of
10726 * user-specified test case.
10728 * @param test_case Test case descriptor to use.
10730 * @return Requested string.
10732 std::string GPUShaderFP64Test8::getComputeShaderBody(const _test_case& test_case)
10734 std::stringstream result_sstream;
10736 /* Form the body */
10737 result_sstream << "#version 420\n"
10738 "#extension GL_ARB_compute_shader : require\n"
10740 "layout(local_size_x = 1) in;\n"
10744 << getGeneralBody(test_case) << "}\n";
10746 /* Return the body */
10747 return result_sstream.str();
10750 /** Retrieves body of a fragment shader that should be used for the purpose of
10751 * user-specified test case.
10753 * @param test_case Test case descriptor to use.
10755 * @return Requested string.
10757 std::string GPUShaderFP64Test8::getFragmentShaderBody(const _test_case& test_case)
10759 std::stringstream result_sstream;
10761 /* Form the body */
10762 result_sstream << "#version 420\n"
10766 << getGeneralBody(test_case) << "}\n"
10769 /* Return the body */
10770 return result_sstream.str();
10773 /** Returns a GLSL line that defines and initializes a variable as described by
10774 * user-specified test case descriptor.
10776 * @param test_case Test case descriptor to use for the query.
10778 * @return As per description
10780 std::string GPUShaderFP64Test8::getGeneralBody(const _test_case& test_case)
10782 std::stringstream result_sstream;
10784 /* Form the body */
10785 std::string variable_type_string = Utils::getVariableTypeString(test_case.type);
10787 result_sstream << variable_type_string << " src = " << variable_type_string << "(";
10789 for (_argument_list_const_iterator argument_list_iterator = test_case.argument_list.begin();
10790 argument_list_iterator != test_case.argument_list.end(); argument_list_iterator++)
10792 const Utils::_variable_type argument_variable_type = *argument_list_iterator;
10793 std::string argument_variable_type_string = Utils::getVariableTypeString(argument_variable_type);
10794 const unsigned int argument_n_components = Utils::getNumberOfComponentsForVariableType(argument_variable_type);
10796 if (argument_list_iterator != test_case.argument_list.begin())
10798 result_sstream << ", ";
10801 result_sstream << argument_variable_type_string << "(";
10803 for (unsigned int n_component = 0; n_component < argument_n_components; ++n_component)
10805 result_sstream << (double)(n_component + 1);
10807 if (n_component != (argument_n_components - 1))
10809 result_sstream << ", ";
10811 } /* for (all argument components) */
10813 result_sstream << ")";
10814 } /* for (all arguments) */
10816 result_sstream << ");\n";
10818 return result_sstream.str();
10821 /** Retrieves body of a geometry shader that should be used for the purpose of
10822 * user-specified test case.
10824 * @param test_case Test case descriptor to use.
10826 * @return Requested string.
10828 std::string GPUShaderFP64Test8::getGeometryShaderBody(const _test_case& test_case)
10830 std::stringstream result_sstream;
10832 /* Form the body */
10833 result_sstream << "#version 420\n"
10835 "layout(points) in;\n"
10836 "layout(max_vertices=1, points) out;\n"
10840 << getGeneralBody(test_case) << "}\n"
10844 return result_sstream.str();
10847 /** Retrieves body of a tesellation control shader that should be used for the purpose of
10848 * user-specified test case.
10850 * @param test_case Test case descriptor to use.
10852 * @return Requested string.
10854 std::string GPUShaderFP64Test8::getTessellationControlShaderBody(const _test_case& test_case)
10856 std::stringstream result_sstream;
10858 /* Form the body */
10859 result_sstream << "#version 420\n"
10861 "layout(vertices=4) out;\n"
10865 << getGeneralBody(test_case) << "}\n"
10868 /* Return the body */
10869 return result_sstream.str();
10872 /** Retrieves body of a tessellation evaluation shader that should be used for the purpose of
10873 * user-specified test case.
10875 * @param test_case Test case descriptor to use.
10877 * @return Requested string.
10879 std::string GPUShaderFP64Test8::getTessellationEvaluationShaderBody(const _test_case& test_case)
10881 std::stringstream result_sstream;
10883 /* Form the body */
10884 result_sstream << "#version 420\n"
10886 "layout(isolines) in;\n"
10890 << getGeneralBody(test_case) << "}\n"
10893 /* Return the body */
10894 return result_sstream.str();
10897 /** Retrieves body of a vertex shader that should be used for the purpose of
10898 * user-specified test case.
10900 * @param test_case Test case descriptor to use.
10902 * @return Requested string.
10904 std::string GPUShaderFP64Test8::getVertexShaderBody(const _test_case& test_case)
10906 std::stringstream result_sstream;
10908 /* Form the body */
10909 result_sstream << "#version 420\n"
10913 << getGeneralBody(test_case) << "}\n"
10916 return result_sstream.str();
10919 /** Initializes shader objects required to run the test. */
10920 void GPUShaderFP64Test8::initTest()
10922 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10924 /* Generate shader objects */
10926 /* Compute shader support and GL 4.2 required */
10927 if ((true == m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader")) &&
10928 (true == Utils::isGLVersionAtLeast(gl, 4 /* major */, 2 /* minor */)))
10930 m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
10933 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
10934 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
10935 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
10936 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
10937 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
10939 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
10942 /** Assigns shader bodies to all shader objects that will be used for a single iteration.
10944 * @param test_case Test case descriptor to generate the shader bodies for.
10946 void GPUShaderFP64Test8::initIteration(_test_case& test_case)
10948 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10950 test_case.cs_shader_body = getComputeShaderBody(test_case);
10951 test_case.fs_shader_body = getFragmentShaderBody(test_case);
10952 test_case.gs_shader_body = getGeometryShaderBody(test_case);
10953 test_case.tc_shader_body = getTessellationControlShaderBody(test_case);
10954 test_case.te_shader_body = getTessellationEvaluationShaderBody(test_case);
10955 test_case.vs_shader_body = getVertexShaderBody(test_case);
10957 /* Assign the bodies to relevant shaders */
10958 const char* cs_body_raw_ptr = test_case.cs_shader_body.c_str();
10959 const char* fs_body_raw_ptr = test_case.fs_shader_body.c_str();
10960 const char* gs_body_raw_ptr = test_case.gs_shader_body.c_str();
10961 const char* tc_body_raw_ptr = test_case.tc_shader_body.c_str();
10962 const char* te_body_raw_ptr = test_case.te_shader_body.c_str();
10963 const char* vs_body_raw_ptr = test_case.vs_shader_body.c_str();
10965 /* m_cs_id is initialized only if compute_shader is supported */
10968 gl.shaderSource(m_cs_id, 1 /* count */, &cs_body_raw_ptr, DE_NULL /* length */);
10971 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, DE_NULL /* length */);
10972 gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, DE_NULL /* length */);
10973 gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, DE_NULL /* length */);
10974 gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, DE_NULL /* length */);
10975 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
10976 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
10979 /** Executes test iteration.
10981 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
10983 tcu::TestNode::IterateResult GPUShaderFP64Test8::iterate()
10985 /* Do not execute the test if GL_ARB_texture_view is not supported */
10986 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
10988 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
10991 /* Initialize GL objects needed to run the tests */
10994 /* Build iteration array to run the tests in an automated manner */
10995 const Utils::_variable_type variable_types[] = { Utils::VARIABLE_TYPE_DMAT2, Utils::VARIABLE_TYPE_DMAT2X3,
10996 Utils::VARIABLE_TYPE_DMAT2X4, Utils::VARIABLE_TYPE_DMAT3,
10997 Utils::VARIABLE_TYPE_DMAT3X2, Utils::VARIABLE_TYPE_DMAT3X4,
10998 Utils::VARIABLE_TYPE_DMAT4, Utils::VARIABLE_TYPE_DMAT4X2,
10999 Utils::VARIABLE_TYPE_DMAT4X3, Utils::VARIABLE_TYPE_DOUBLE,
11000 Utils::VARIABLE_TYPE_DVEC2, Utils::VARIABLE_TYPE_DVEC3,
11001 Utils::VARIABLE_TYPE_DVEC4 };
11002 const unsigned int n_variable_types = sizeof(variable_types) / sizeof(variable_types[0]);
11004 for (unsigned int n_variable_type = 0; n_variable_type < n_variable_types; ++n_variable_type)
11006 const Utils::_variable_type variable_type = variable_types[n_variable_type];
11008 /* Construct a set of argument lists valid for the variable type considered */
11009 _argument_lists argument_lists = getArgumentListsForVariableType(variable_type);
11011 for (_argument_lists_const_iterator argument_list_iterator = argument_lists.begin();
11012 argument_list_iterator != argument_lists.end(); argument_list_iterator++)
11014 /* Constructor thwe test case descriptor */
11015 _test_case test_case;
11017 test_case.argument_list = *argument_list_iterator;
11018 test_case.type = variable_type;
11020 /* Initialize a program object we will use to perform the casting */
11021 initIteration(test_case);
11023 /* See if the shader compiles. */
11024 m_has_test_passed &= executeIteration(test_case);
11025 } /* for (all argument lists) */
11026 } /* for (all variable types) */
11029 if (m_has_test_passed)
11031 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
11035 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11043 * @param context Rendering context.
11046 GPUShaderFP64Test9::GPUShaderFP64Test9(deqp::Context& context)
11047 : TestCase(context, "operators", "Verifies that general and relational operators work "
11048 "correctly when used against double-precision floating-"
11050 , m_has_test_passed(true)
11056 /* Left blank intentionally */
11059 /** Deinitializes all ES objects that may have been created during
11062 void GPUShaderFP64Test9::deinit()
11064 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11068 gl.deleteProgram(m_po_id);
11073 if (m_xfb_bo_id != 0)
11075 gl.deleteBuffers(1, &m_xfb_bo_id);
11082 gl.deleteVertexArrays(1, &m_vao_id);
11084 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() call failed.");
11089 gl.deleteShader(m_vs_id);
11095 /** Executes a single test iteration using user-specified test case properties.
11097 * @param test_case Test case descriptor.
11099 * @return true if the pass was successful, false if the test should fail.
11101 bool GPUShaderFP64Test9::executeTestIteration(const _test_case& test_case)
11103 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11104 bool result = true;
11106 /* Activate the test program object */
11107 gl.useProgram(m_po_id);
11108 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
11110 /* Draw a single point with XFB enabled */
11111 gl.beginTransformFeedback(GL_POINTS);
11112 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
11114 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
11115 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
11117 gl.endTransformFeedback();
11118 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
11120 /* Map the XFB BO into process space */
11121 const void* xfb_data_ptr = gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
11123 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
11125 result = verifyXFBData(test_case, (const unsigned char*)xfb_data_ptr);
11128 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
11129 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
11134 /** Performs a matrix multiplication, given types of l-side and r-side matrices and stores the result
11135 * under user-specified location.
11137 * @param matrix_a_type Type of the l-side matrix.
11138 * @param matrix_a_data Row-ordered data of l-side matrix.
11139 * @param matrix_b_type Type of the r-side matrix.
11140 * @param matrix_b_data Row-ordered data of r-side matrix.
11141 * @param out_result_ptr Deref to be used to store the multiplication result.
11143 void GPUShaderFP64Test9::getMatrixMultiplicationResult(const Utils::_variable_type& matrix_a_type,
11144 const std::vector<double>& matrix_a_data,
11145 const Utils::_variable_type& matrix_b_type,
11146 const std::vector<double>& matrix_b_data, double* out_result_ptr)
11148 (void)matrix_b_type;
11149 using namespace tcu;
11150 /* To keep the code maintainable, we only consider cases relevant for this test */
11151 switch (matrix_a_type)
11153 case Utils::VARIABLE_TYPE_DMAT2:
11155 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT2);
11157 tcu::Matrix2d matrix_a(&matrix_a_data[0]);
11158 tcu::Matrix2d matrix_b(&matrix_b_data[0]);
11159 tcu::Matrix2d result;
11161 matrix_a = transpose(matrix_a);
11162 matrix_b = transpose(matrix_b);
11163 result = matrix_a * matrix_b;
11165 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 2 * 2);
11169 case Utils::VARIABLE_TYPE_DMAT2X3:
11171 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT3X2);
11173 tcu::Matrix<double, 2, 3> matrix_a(&matrix_a_data[0]);
11174 tcu::Matrix<double, 3, 2> matrix_a_transposed;
11175 tcu::Matrix<double, 3, 2> matrix_b(&matrix_b_data[0]);
11176 tcu::Matrix<double, 2, 3> matrix_b_transposed;
11177 tcu::Matrix<double, 3, 3> result;
11179 matrix_a_transposed = transpose(matrix_a);
11180 matrix_b_transposed = transpose(matrix_b);
11181 result = matrix_a_transposed * matrix_b_transposed;
11183 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 3 * 3);
11187 case Utils::VARIABLE_TYPE_DMAT2X4:
11189 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT4X2);
11191 tcu::Matrix<double, 2, 4> matrix_a(&matrix_a_data[0]);
11192 tcu::Matrix<double, 4, 2> matrix_a_transposed;
11193 tcu::Matrix<double, 4, 2> matrix_b(&matrix_b_data[0]);
11194 tcu::Matrix<double, 2, 4> matrix_b_transposed;
11195 tcu::Matrix<double, 4, 4> result;
11197 matrix_a_transposed = transpose(matrix_a);
11198 matrix_b_transposed = transpose(matrix_b);
11199 result = matrix_a_transposed * matrix_b_transposed;
11201 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 4 * 4);
11205 case Utils::VARIABLE_TYPE_DMAT3:
11207 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT3);
11209 tcu::Matrix<double, 3, 3> matrix_a(&matrix_a_data[0]);
11210 tcu::Matrix<double, 3, 3> matrix_b(&matrix_b_data[0]);
11211 tcu::Matrix<double, 3, 3> result;
11213 matrix_a = transpose(matrix_a);
11214 matrix_b = transpose(matrix_b);
11215 result = matrix_a * matrix_b;
11217 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 3 * 3);
11221 case Utils::VARIABLE_TYPE_DMAT3X2:
11223 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT2X3);
11225 tcu::Matrix<double, 3, 2> matrix_a(&matrix_a_data[0]);
11226 tcu::Matrix<double, 2, 3> matrix_a_transposed;
11227 tcu::Matrix<double, 2, 3> matrix_b(&matrix_b_data[0]);
11228 tcu::Matrix<double, 3, 2> matrix_b_transposed;
11229 tcu::Matrix<double, 2, 2> result;
11231 matrix_a_transposed = transpose(matrix_a);
11232 matrix_b_transposed = transpose(matrix_b);
11233 result = matrix_a_transposed * matrix_b_transposed;
11235 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 2 * 2);
11239 case Utils::VARIABLE_TYPE_DMAT3X4:
11241 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT4X3);
11243 tcu::Matrix<double, 3, 4> matrix_a(&matrix_a_data[0]);
11244 tcu::Matrix<double, 4, 3> matrix_a_transposed;
11245 tcu::Matrix<double, 4, 3> matrix_b(&matrix_b_data[0]);
11246 tcu::Matrix<double, 3, 4> matrix_b_transposed;
11247 tcu::Matrix<double, 4, 4> result;
11249 matrix_a_transposed = transpose(matrix_a);
11250 matrix_b_transposed = transpose(matrix_b);
11251 result = matrix_a_transposed * matrix_b_transposed;
11253 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 4 * 4);
11257 case Utils::VARIABLE_TYPE_DMAT4:
11259 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT4);
11261 tcu::Matrix<double, 4, 4> matrix_a(&matrix_a_data[0]);
11262 tcu::Matrix<double, 4, 4> matrix_b(&matrix_b_data[0]);
11263 tcu::Matrix<double, 4, 4> result;
11265 matrix_a = transpose(matrix_a);
11266 matrix_b = transpose(matrix_b);
11267 result = matrix_a * matrix_b;
11269 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 4 * 4);
11273 case Utils::VARIABLE_TYPE_DMAT4X2:
11275 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT2X4);
11277 tcu::Matrix<double, 4, 2> matrix_a(&matrix_a_data[0]);
11278 tcu::Matrix<double, 2, 4> matrix_a_transposed;
11279 tcu::Matrix<double, 2, 4> matrix_b(&matrix_b_data[0]);
11280 tcu::Matrix<double, 4, 2> matrix_b_transposed;
11281 tcu::Matrix<double, 2, 2> result;
11283 matrix_a_transposed = transpose(matrix_a);
11284 matrix_b_transposed = transpose(matrix_b);
11285 result = matrix_a_transposed * matrix_b_transposed;
11287 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 2 * 2);
11291 case Utils::VARIABLE_TYPE_DMAT4X3:
11293 DE_ASSERT(matrix_b_type == Utils::VARIABLE_TYPE_DMAT3X4);
11295 tcu::Matrix<double, 4, 3> matrix_a(&matrix_a_data[0]);
11296 tcu::Matrix<double, 3, 4> matrix_a_transposed;
11297 tcu::Matrix<double, 3, 4> matrix_b(&matrix_b_data[0]);
11298 tcu::Matrix<double, 4, 3> matrix_b_transposed;
11299 tcu::Matrix<double, 3, 3> result;
11301 matrix_a_transposed = transpose(matrix_a);
11302 matrix_b_transposed = transpose(matrix_b);
11303 result = matrix_a_transposed * matrix_b_transposed;
11305 memcpy(out_result_ptr, result.getColumnMajorData().getPtr(), sizeof(double) * 3 * 3);
11311 TCU_FAIL("Unrecognized matrix A type");
11313 } /* switch (matrix_a_type) */
11316 /** Returns GLSL operator representation of the user-specified operation.
11318 * @param operation_type Internal operation type to retrieve the operator for.
11320 * @return As per description.
11322 const char* GPUShaderFP64Test9::getOperatorForOperationType(const _operation_type& operation_type)
11324 const char* result = NULL;
11326 switch (operation_type)
11328 case OPERATION_TYPE_ADDITION:
11331 case OPERATION_TYPE_DIVISION:
11334 case OPERATION_TYPE_MULTIPLICATION:
11337 case OPERATION_TYPE_SUBTRACTION:
11341 case OPERATION_TYPE_PRE_DECREMENTATION:
11342 case OPERATION_TYPE_POST_DECREMENTATION:
11349 case OPERATION_TYPE_PRE_INCREMENTATION:
11350 case OPERATION_TYPE_POST_INCREMENTATION:
11359 TCU_FAIL("Unrecognized operation type");
11361 } /* switch(operation_type) */
11366 /** Returns a string representing user-specified operation type.
11368 * @param operation_type Operation type to return the literal for.
11370 * @return Requested string.
11372 std::string GPUShaderFP64Test9::getOperationTypeString(const _operation_type& operation_type)
11374 std::string result = "[?]";
11376 switch (operation_type)
11378 case OPERATION_TYPE_ADDITION:
11379 result = "addition";
11381 case OPERATION_TYPE_DIVISION:
11382 result = "division";
11384 case OPERATION_TYPE_MULTIPLICATION:
11385 result = "multiplication";
11387 case OPERATION_TYPE_SUBTRACTION:
11388 result = "subtraction";
11390 case OPERATION_TYPE_PRE_DECREMENTATION:
11391 result = "pre-decrementation";
11393 case OPERATION_TYPE_PRE_INCREMENTATION:
11394 result = "pre-incrementation";
11396 case OPERATION_TYPE_POST_DECREMENTATION:
11397 result = "post-decrementation";
11399 case OPERATION_TYPE_POST_INCREMENTATION:
11400 result = "post-incrementation";
11405 TCU_FAIL("Unrecognized operation type");
11412 /** Returns body of a vertex shader that should be used for user-specified test case
11415 * @param test_case Test case descriptor.
11417 * @return Requested GLSL shader body.
11419 std::string GPUShaderFP64Test9::getVertexShaderBody(_test_case& test_case)
11421 std::stringstream result_sstream;
11422 std::string result_variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
11423 std::string variable_type_fp_string = Utils::getFPVariableTypeStringForVariableType(test_case.variable_type);
11424 std::string variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
11425 const unsigned int n_variable_components = Utils::getNumberOfComponentsForVariableType(test_case.variable_type);
11427 /* If we are to multiply matrices, we will need to use a different type
11428 * for the result variable if either of the matrices is not square.
11430 if (test_case.operation_type == OPERATION_TYPE_MULTIPLICATION &&
11431 Utils::isMatrixVariableType(test_case.variable_type))
11433 Utils::_variable_type result_variable_type;
11434 Utils::_variable_type transposed_matrix_variable_type =
11435 Utils::getTransposedMatrixVariableType(test_case.variable_type);
11437 result_variable_type =
11438 Utils::getPostMatrixMultiplicationVariableType(test_case.variable_type, transposed_matrix_variable_type);
11439 result_variable_type_string = Utils::getVariableTypeString(result_variable_type);
11441 test_case.result_variable_type = result_variable_type;
11444 /* Form the pre-amble */
11445 result_sstream << "#version 400\n"
11448 /* Add output variables */
11450 << result_variable_type_string << " result;\n"
11451 "out ivec2 result_lt;\n"
11452 "out ivec2 result_lte;\n"
11453 "out ivec2 result_gt;\n"
11454 "out ivec2 result_gte;\n"
11458 /* Form reference values */
11459 result_sstream << variable_type_string << " reference1 = " << variable_type_string << "(";
11461 for (unsigned int n_variable_component = 0; n_variable_component < n_variable_components; ++n_variable_component)
11463 result_sstream << (n_variable_component + 1);
11465 if (n_variable_component != (n_variable_components - 1))
11467 result_sstream << ", ";
11469 } /* for (all variable components) */
11471 result_sstream << ");\n";
11473 for (unsigned int n_ref2_case = 0; n_ref2_case < 2; /* single- and double-precision cases */
11476 Utils::_variable_type compatible_variable_type = test_case.variable_type;
11478 if (Utils::isMatrixVariableType(compatible_variable_type) &&
11479 test_case.operation_type == OPERATION_TYPE_MULTIPLICATION)
11481 compatible_variable_type = Utils::getTransposedMatrixVariableType(compatible_variable_type);
11484 std::string ref2_variable_type_fp_string =
11485 Utils::getFPVariableTypeStringForVariableType(compatible_variable_type);
11486 std::string ref2_variable_type_string = Utils::getVariableTypeString(compatible_variable_type);
11487 std::string ref2_variable_type = (n_ref2_case == 0) ? ref2_variable_type_fp_string : ref2_variable_type_string;
11488 std::string ref2_variable_name = (n_ref2_case == 0) ? "reference2f" : "reference2";
11490 result_sstream << ref2_variable_type << " " << ref2_variable_name << " = " << ref2_variable_type << "(";
11492 for (unsigned int n_variable_component = 0; n_variable_component < n_variable_components;
11493 ++n_variable_component)
11495 result_sstream << (n_variable_components - (n_variable_component + 1));
11497 if (n_variable_component != (n_variable_components - 1))
11499 result_sstream << ", ";
11501 } /* for (all variable components) */
11503 result_sstream << ");\n";
11504 } /* for (both reference2 declarations) */
11506 /* Add actual body */
11507 result_sstream << "\n"
11510 if (test_case.operation_type == OPERATION_TYPE_PRE_DECREMENTATION ||
11511 test_case.operation_type == OPERATION_TYPE_PRE_INCREMENTATION)
11513 result_sstream << getOperatorForOperationType(test_case.operation_type);
11516 result_sstream << "reference1 ";
11518 if (test_case.operation_type == OPERATION_TYPE_PRE_DECREMENTATION ||
11519 test_case.operation_type == OPERATION_TYPE_PRE_INCREMENTATION ||
11520 test_case.operation_type == OPERATION_TYPE_POST_DECREMENTATION ||
11521 test_case.operation_type == OPERATION_TYPE_POST_INCREMENTATION)
11523 if (test_case.operation_type == OPERATION_TYPE_POST_DECREMENTATION ||
11524 test_case.operation_type == OPERATION_TYPE_POST_INCREMENTATION)
11526 result_sstream << getOperatorForOperationType(test_case.operation_type);
11531 result_sstream << getOperatorForOperationType(test_case.operation_type) << " reference2";
11534 result_sstream << ";\n";
11536 if (Utils::isScalarVariableType(test_case.variable_type))
11538 result_sstream << "result_lt [0] = (reference1 < reference2) ? 1 : 0;\n"
11539 "result_lt [1] = (reference1 < reference2f) ? 1 : 0;\n"
11540 "result_lte[0] = (reference1 <= reference2) ? 1 : 0;\n"
11541 "result_lte[1] = (reference1 <= reference2f) ? 1 : 0;\n"
11542 "result_gt [0] = (reference1 > reference2) ? 1 : 0;\n"
11543 "result_gt [1] = (reference1 > reference2f) ? 1 : 0;\n"
11544 "result_gte[0] = (reference1 >= reference2) ? 1 : 0;\n"
11545 "result_gte[1] = (reference1 >= reference2f) ? 1 : 0;\n";
11549 result_sstream << "result_lt [0] = 1;\n"
11550 "result_lt [1] = 1;\n"
11551 "result_lte[0] = 1;\n"
11552 "result_lte[1] = 1;\n"
11553 "result_gt [0] = 1;\n"
11554 "result_gt [1] = 1;\n"
11555 "result_gte[0] = 1;\n"
11556 "result_gte[1] = 1;\n";
11559 result_sstream << "}\n";
11562 return result_sstream.str();
11565 /** Initializes all GL objects required to run the test.
11567 * This function can throw a TestError exception if the implementation misbehaves.
11569 void GPUShaderFP64Test9::initTest()
11571 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11573 /* Create program & vertex shader objects */
11574 m_po_id = gl.createProgram();
11575 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
11577 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() or glCreateShader() call failed.");
11579 /* Attach the shader to the program */
11580 gl.attachShader(m_po_id, m_vs_id);
11581 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
11583 /* Set up a buffer object */
11584 gl.genBuffers(1, &m_xfb_bo_id);
11585 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
11587 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfb_bo_id);
11588 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
11590 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_xfb_bo_id);
11591 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
11593 /* Set up a vertex array object */
11594 gl.genVertexArrays(1, &m_vao_id);
11595 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
11597 gl.bindVertexArray(m_vao_id);
11598 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
11601 /** Initializes all GL objects required to run an iteration described by
11602 * user-specified test case descriptor.
11604 * @param test_case Test case descriptor to use for the initialization.
11606 void GPUShaderFP64Test9::initTestIteration(_test_case& test_case)
11608 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
11609 std::string vs_body = getVertexShaderBody(test_case);
11610 const char* vs_body_raw_ptr = vs_body.c_str();
11612 /* Store the shader's body */
11613 test_case.vs_body = vs_body;
11615 /* Try to compile the shader */
11616 glw::GLint compile_status = GL_FALSE;
11618 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
11619 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
11621 gl.compileShader(m_vs_id);
11622 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
11624 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
11625 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
11627 if (compile_status != GL_TRUE)
11629 TCU_FAIL("Test shader compilation failed.");
11632 /* Configure XFB */
11633 const char* xfb_names[] = { "result", "result_lt", "result_lte", "result_gt", "result_gte" };
11634 const unsigned int n_xfb_names = sizeof(xfb_names) / sizeof(xfb_names[0]);
11636 gl.transformFeedbackVaryings(m_po_id, n_xfb_names, xfb_names, GL_INTERLEAVED_ATTRIBS);
11637 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
11639 /* Try to link the program */
11640 glw::GLint link_status = GL_FALSE;
11642 gl.linkProgram(m_po_id);
11643 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
11645 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
11646 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
11648 if (link_status != GL_TRUE)
11650 TCU_FAIL("Test program linking failure");
11653 /* Set up XFB BO data storage */
11654 const unsigned int result_variable_size = static_cast<unsigned int>(
11655 Utils::getNumberOfComponentsForVariableType(test_case.result_variable_type) * sizeof(double));
11656 const unsigned int xfb_bo_size = static_cast<unsigned int>(
11657 result_variable_size + sizeof(int) * 2 /* ivec2s */ * 4); /* result_ output variables */
11659 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_bo_size, DE_NULL /* data */, GL_STATIC_DRAW);
11660 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
11663 /** Executes test iteration.
11665 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
11667 tcu::TestNode::IterateResult GPUShaderFP64Test9::iterate()
11669 /* Do not execute the test if GL_ARB_texture_view is not supported */
11670 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
11672 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
11675 /* Initialize all ES objects required to run all the checks */
11678 /* Iterate through all variable types we want to test */
11679 const Utils::_variable_type variable_types[] = { Utils::VARIABLE_TYPE_DMAT2, Utils::VARIABLE_TYPE_DMAT2X3,
11680 Utils::VARIABLE_TYPE_DMAT2X4, Utils::VARIABLE_TYPE_DMAT3,
11681 Utils::VARIABLE_TYPE_DMAT3X2, Utils::VARIABLE_TYPE_DMAT3X4,
11682 Utils::VARIABLE_TYPE_DMAT4, Utils::VARIABLE_TYPE_DMAT4X2,
11683 Utils::VARIABLE_TYPE_DMAT4X3, Utils::VARIABLE_TYPE_DOUBLE,
11684 Utils::VARIABLE_TYPE_DVEC2, Utils::VARIABLE_TYPE_DVEC3,
11685 Utils::VARIABLE_TYPE_DVEC4 };
11686 const unsigned int n_variable_types = sizeof(variable_types) / sizeof(variable_types[0]);
11688 for (unsigned int n_variable_type = 0; n_variable_type < n_variable_types; ++n_variable_type)
11690 /* Iterate through all operation types we want to check */
11691 for (unsigned int n_operation_type = 0; n_operation_type < OPERATION_TYPE_COUNT; ++n_operation_type)
11693 _operation_type operation_type = (_operation_type)n_operation_type;
11694 const Utils::_variable_type& variable_type = variable_types[n_variable_type];
11696 /* Construct test case descriptor */
11697 _test_case test_case;
11699 test_case.operation_type = operation_type;
11700 test_case.result_variable_type = variable_type;
11701 test_case.variable_type = variable_type;
11703 /* Run the iteration */
11704 initTestIteration(test_case);
11706 m_has_test_passed &= executeTestIteration(test_case);
11707 } /* for (all operation types) */
11708 } /* for (all variable types) */
11711 if (m_has_test_passed)
11713 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
11717 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
11723 /** Verifies data XFBed out by the draw call for user-specified test case
11726 * @param test_case Test case descriptor
11727 * @param xfb_data Buffer holding the data XFBed out during the draw call.
11728 * Must not be NULL.
11730 * @return true if the data was found to be correct, false otherwise.
11732 bool GPUShaderFP64Test9::verifyXFBData(const _test_case& test_case, const unsigned char* xfb_data)
11734 const double epsilon = 1e-5;
11735 const unsigned int n_result_components =
11736 Utils::getNumberOfComponentsForVariableType(test_case.result_variable_type);
11737 bool result = true;
11738 const double* xfb_data_result = (const double*)xfb_data;
11739 const int* xfb_data_result_lt = (const int*)(xfb_data_result + n_result_components);
11740 const int* xfb_data_result_lte = (const int*)xfb_data_result_lt + 2; /* cast/non-cast cases */
11741 const int* xfb_data_result_gt = (const int*)xfb_data_result_lte + 2; /* cast/non-cast cases */
11742 const int* xfb_data_result_gte = (const int*)xfb_data_result_gt + 2; /* cast/non-cast cases */
11744 /* Prepare reference values */
11746 std::vector<double> reference1;
11747 std::vector<double> reference2;
11749 if (test_case.operation_type == OPERATION_TYPE_PRE_INCREMENTATION ||
11750 test_case.operation_type == OPERATION_TYPE_POST_INCREMENTATION)
11754 else if (test_case.operation_type == OPERATION_TYPE_PRE_DECREMENTATION ||
11755 test_case.operation_type == OPERATION_TYPE_POST_DECREMENTATION)
11764 if (Utils::isMatrixVariableType(test_case.variable_type))
11766 /* Matrices may be of different sizes so we need to compute the
11767 * reference values separately for each matrix
11769 const Utils::_variable_type matrix_a_type = test_case.variable_type;
11770 const Utils::_variable_type matrix_b_type = Utils::getTransposedMatrixVariableType(test_case.variable_type);
11771 const unsigned int n_matrix_a_components = Utils::getNumberOfComponentsForVariableType(matrix_a_type);
11772 const unsigned int n_matrix_b_components = Utils::getNumberOfComponentsForVariableType(matrix_b_type);
11774 for (unsigned int n_component = 0; n_component < n_matrix_a_components; ++n_component)
11776 reference1.push_back(modifier + n_component + 1);
11779 for (unsigned int n_component = 0; n_component < n_matrix_b_components; ++n_component)
11781 reference2.push_back(n_matrix_b_components - (n_component + 1));
11783 } /* if (Utils::isMatrixVariableType(test_case.variable_type) */
11786 /* Generate as many components as will be expected for the result variable */
11787 for (unsigned int n_result_component = 0; n_result_component < n_result_components; ++n_result_component)
11789 reference1.push_back(modifier + n_result_component + 1);
11790 reference2.push_back(n_result_components - (n_result_component + 1));
11794 /* Verify the result value(s) */
11795 if (test_case.operation_type == OPERATION_TYPE_MULTIPLICATION &&
11796 Utils::isMatrixVariableType(test_case.variable_type))
11798 /* Matrix multiplication */
11799 double expected_result_data[4 * 4];
11800 Utils::_variable_type matrix_a_type = test_case.variable_type;
11801 Utils::_variable_type matrix_b_type = Utils::getTransposedMatrixVariableType(test_case.variable_type);
11803 getMatrixMultiplicationResult(matrix_a_type, reference1, matrix_b_type, reference2, expected_result_data);
11805 for (unsigned int n_component = 0; n_component < n_result_components; ++n_component)
11807 if (de::abs(xfb_data_result[n_component] - expected_result_data[n_component]) > epsilon)
11809 std::stringstream log_sstream;
11811 log_sstream << "Data returned for " << Utils::getVariableTypeString(matrix_a_type) << " * "
11812 << Utils::getVariableTypeString(matrix_b_type)
11813 << " matrix multiplication was incorrect; expected:(";
11815 for (unsigned int n_logged_component = 0; n_logged_component < n_result_components;
11816 ++n_logged_component)
11818 log_sstream << expected_result_data[n_logged_component];
11820 if (n_logged_component != (n_result_components - 1))
11822 log_sstream << ", ";
11824 } /* for (all components to be logged) */
11826 log_sstream << "), retrieved:(";
11828 for (unsigned int n_logged_component = 0; n_logged_component < n_result_components;
11829 ++n_logged_component)
11831 log_sstream << xfb_data_result[n_logged_component];
11833 if (n_logged_component != (n_result_components - 1))
11835 log_sstream << ", ";
11837 } /* for (all components to be logged) */
11839 log_sstream << ")";
11841 m_testCtx.getLog() << tcu::TestLog::Message << log_sstream.str().c_str() << tcu::TestLog::EndMessage;
11846 } /* for (all result components) */
11847 } /* if (dealing with matrix multiplication) */
11850 for (unsigned int n_component = 0; n_component < n_result_components; ++n_component)
11852 double expected_value = reference1[n_component];
11854 switch (test_case.operation_type)
11856 case OPERATION_TYPE_ADDITION:
11857 expected_value += reference2[n_component];
11859 case OPERATION_TYPE_DIVISION:
11860 expected_value /= reference2[n_component];
11862 case OPERATION_TYPE_MULTIPLICATION:
11863 expected_value *= reference2[n_component];
11865 case OPERATION_TYPE_SUBTRACTION:
11866 expected_value -= reference2[n_component];
11869 case OPERATION_TYPE_PRE_DECREMENTATION:
11870 case OPERATION_TYPE_PRE_INCREMENTATION:
11872 /* Modifier already applied */
11876 case OPERATION_TYPE_POST_DECREMENTATION:
11877 case OPERATION_TYPE_POST_INCREMENTATION:
11879 /* Need to reverse the modification for the purpose of the following check */
11880 expected_value -= modifier;
11887 TCU_FAIL("Unrecognized operation type");
11889 } /* switch (test_case.operation_type) */
11891 if (de::abs(xfb_data_result[n_component] - expected_value) > epsilon)
11893 std::string operation_type_string = getOperationTypeString(test_case.operation_type);
11894 std::string variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
11896 m_testCtx.getLog() << tcu::TestLog::Message << "Value(s) generated for variable type ["
11897 << variable_type_string << "]"
11898 " and operation type ["
11899 << operation_type_string << "]"
11900 " were found invalid."
11901 << tcu::TestLog::EndMessage;
11905 } /* if (test case failed) */
11906 } /* for (all components) */
11909 /* Verify the comparison operation results */
11910 if (Utils::isScalarVariableType(test_case.variable_type))
11912 DE_ASSERT(n_result_components == 1);
11914 const bool expected_result_lt[2] = { reference1[0] < reference2[0], reference1[0] < (float)reference2[0] };
11915 const bool expected_result_lte[2] = { reference1[0] <= reference2[0], reference1[0] <= (float)reference2[0] };
11916 const bool expected_result_gt[2] = { reference1[0] > reference2[0], reference1[0] > (float)reference2[0] };
11917 const bool expected_result_gte[2] = { reference1[0] >= reference2[0], reference1[0] >= (float)reference2[0] };
11919 if ((xfb_data_result_lt[0] ? 1 : 0) != expected_result_lt[0] ||
11920 (xfb_data_result_lt[1] ? 1 : 0) != expected_result_lt[1])
11922 std::string operation_type_string = getOperationTypeString(test_case.operation_type);
11923 std::string variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
11925 m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for lower-than operator used for "
11927 << variable_type_string << "]"
11928 "and operation type ["
11929 << operation_type_string << "]"
11930 "was found invalid; expected:("
11931 << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
11932 << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
11933 << tcu::TestLog::EndMessage;
11938 if ((xfb_data_result_lte[0] ? 1 : 0) != expected_result_lte[0] ||
11939 (xfb_data_result_lte[1] ? 1 : 0) != expected_result_lte[1])
11941 std::string operation_type_string = getOperationTypeString(test_case.operation_type);
11942 std::string variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
11944 m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for lower-than-or-equal operator used for "
11946 << variable_type_string << "]"
11947 "and operation type ["
11948 << operation_type_string << "]"
11949 "was found invalid; expected:("
11950 << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
11951 << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
11952 << tcu::TestLog::EndMessage;
11957 if ((xfb_data_result_gt[0] ? 1 : 0) != expected_result_gt[0] ||
11958 (xfb_data_result_gt[1] ? 1 : 0) != expected_result_gt[1])
11960 std::string operation_type_string = getOperationTypeString(test_case.operation_type);
11961 std::string variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
11963 m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for greater-than operator used for "
11965 << variable_type_string << "]"
11966 "and operation type ["
11967 << operation_type_string << "]"
11968 "was found invalid; expected:("
11969 << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
11970 << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
11971 << tcu::TestLog::EndMessage;
11976 if ((xfb_data_result_gte[0] ? 1 : 0) != expected_result_gte[0] ||
11977 (xfb_data_result_gte[1] ? 1 : 0) != expected_result_gte[1])
11979 std::string operation_type_string = getOperationTypeString(test_case.operation_type);
11980 std::string variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
11982 m_testCtx.getLog() << tcu::TestLog::Message
11983 << "Values reported for greater-than-or-equal operator used for "
11985 << variable_type_string << "]"
11986 "and operation type ["
11987 << operation_type_string << "]"
11988 "was found invalid; expected:("
11989 << expected_result_lt[0] << ", " << expected_result_lt[1] << "); found:("
11990 << xfb_data_result_lt[0] << ", " << xfb_data_result_lt[1] << ")."
11991 << tcu::TestLog::EndMessage;
11995 } /* if (Utils::isScalarVariableType(test_case.variable_type) ) */
11998 if (xfb_data_result_lt[0] != 1 || xfb_data_result_lt[1] != 1 || xfb_data_result_lte[0] != 1 ||
11999 xfb_data_result_lte[1] != 1 || xfb_data_result_gt[0] != 1 || xfb_data_result_gt[1] != 1 ||
12000 xfb_data_result_gte[0] != 1 || xfb_data_result_gte[1] != 1)
12002 std::string operation_type_string = getOperationTypeString(test_case.operation_type);
12003 std::string variable_type_string = Utils::getVariableTypeString(test_case.variable_type);
12005 m_testCtx.getLog() << tcu::TestLog::Message
12006 << "Invalid value was reported for matrix variable type, for which "
12007 " operator checks are not executed; variable type ["
12008 << variable_type_string << "]"
12009 "and operation type ["
12010 << operation_type_string << "]" << tcu::TestLog::EndMessage;
12019 namespace TypeHelpers
12021 /** Get base type for reference types
12025 template <typename T>
12026 class referenceToType
12032 template <typename T>
12033 class referenceToType<const T&>
12039 /** Maps variable type with enumeration Utils::_variable_type
12043 template <typename T>
12047 class typeInfo<glw::GLboolean>
12050 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_BOOL;
12054 class typeInfo<glw::GLdouble>
12057 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DOUBLE;
12061 class typeInfo<tcu::UVec2>
12064 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_UVEC2;
12068 class typeInfo<tcu::UVec3>
12071 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_UVEC3;
12075 class typeInfo<tcu::UVec4>
12078 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_UVEC4;
12082 class typeInfo<tcu::DVec2>
12085 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DVEC2;
12089 class typeInfo<tcu::DVec3>
12092 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DVEC3;
12096 class typeInfo<tcu::DVec4>
12099 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DVEC4;
12103 class typeInfo<tcu::Matrix<glw::GLdouble, 2, 2> >
12106 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT2;
12110 class typeInfo<tcu::Matrix<glw::GLdouble, 3, 2> >
12113 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT2X3;
12117 class typeInfo<tcu::Matrix<glw::GLdouble, 4, 2> >
12120 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT2X4;
12124 class typeInfo<tcu::Matrix<glw::GLdouble, 3, 3> >
12127 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT3;
12131 class typeInfo<tcu::Matrix<glw::GLdouble, 2, 3> >
12134 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT3X2;
12138 class typeInfo<tcu::Matrix<glw::GLdouble, 4, 3> >
12141 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT3X4;
12145 class typeInfo<tcu::Matrix<glw::GLdouble, 4, 4> >
12148 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT4;
12152 class typeInfo<tcu::Matrix<glw::GLdouble, 2, 4> >
12155 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT4X2;
12159 class typeInfo<tcu::Matrix<glw::GLdouble, 3, 4> >
12162 static const Utils::_variable_type variable_type = Utils::VARIABLE_TYPE_DMAT4X3;
12164 } /* TypeHelpers */
12166 /** Implementations of "math" functions required by "GPUShaderFP64Test10"
12171 template <typename T>
12172 static T clamp(T x, T minVal, T maxVal);
12174 template <int Size>
12175 static tcu::Matrix<glw::GLdouble, Size, Size> cofactors(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix);
12177 template <int Size>
12178 static tcu::Vector<glw::GLuint, Size> convertBvecToUvec(const tcu::Vector<bool, Size>& src);
12180 template <typename T>
12181 static T determinant(T val);
12183 template <typename T>
12184 static T determinant(const tcu::Matrix<T, 2, 2>& mat);
12186 template <typename T>
12187 static T determinant(const tcu::Matrix<T, 3, 3>& mat);
12189 template <typename T>
12190 static T determinant(const tcu::Matrix<T, 4, 4>& mat);
12192 template <int Size>
12193 static tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminate(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix,
12194 glw::GLuint column, glw::GLuint row);
12196 template <int Size>
12197 static tcu::Vector<glw::GLuint, Size> equal(const tcu::Vector<glw::GLdouble, Size>& left,
12198 const tcu::Vector<glw::GLdouble, Size>& right);
12200 static glw::GLdouble fma(glw::GLdouble a, glw::GLdouble b, glw::GLdouble c);
12202 static glw::GLdouble fract(glw::GLdouble val);
12204 template <typename T>
12205 static T frexp(T val, glw::GLint& exp);
12207 template <int Size>
12208 static tcu::Vector<glw::GLuint, Size> greaterThan(const tcu::Vector<glw::GLdouble, Size>& left,
12209 const tcu::Vector<glw::GLdouble, Size>& right);
12211 template <int Size>
12212 static tcu::Vector<glw::GLuint, Size> greaterThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12213 const tcu::Vector<glw::GLdouble, Size>& right);
12215 template <int Size>
12216 static tcu::Matrix<glw::GLdouble, Size, Size> inverse(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix);
12218 static glw::GLdouble inverseSqrt(glw::GLdouble val);
12220 static glw::GLuint isinf_impl(glw::GLdouble val);
12222 static glw::GLuint isnan_impl(glw::GLdouble val);
12224 template <typename T>
12225 static T ldexp(T val, glw::GLint exp);
12227 template <int Size>
12228 static tcu::Vector<glw::GLuint, Size> lessThan(const tcu::Vector<glw::GLdouble, Size>& left,
12229 const tcu::Vector<glw::GLdouble, Size>& right);
12231 template <int Size>
12232 static tcu::Vector<glw::GLuint, Size> lessThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12233 const tcu::Vector<glw::GLdouble, Size>& right);
12235 template <typename T>
12236 static T max(T left, T right);
12238 template <typename T>
12239 static T min(T left, T right);
12241 template <int Size>
12242 static glw::GLdouble minor_impl(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix, glw::GLuint column,
12245 template <typename T>
12246 static T mix(T left, T right, T weight);
12248 template <typename T>
12249 static T mod(T left, T right);
12251 template <typename T>
12252 static T modf(T val, T& integer);
12254 template <typename T>
12255 static T multiply(T left, T right);
12257 template <int Size>
12258 static tcu::Vector<glw::GLuint, Size> notEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12259 const tcu::Vector<glw::GLdouble, Size>& right);
12261 template <int Cols, int Rows>
12262 static tcu::Matrix<glw::GLdouble, Rows, Cols> outerProduct(const tcu::Vector<glw::GLdouble, Rows>& left,
12263 const tcu::Vector<glw::GLdouble, Cols>& right);
12265 static glw::GLdouble packDouble2x32(const tcu::UVec2& in);
12267 template <typename T>
12268 static T round(T t);
12270 template <typename T>
12271 static T roundEven(T t);
12273 template <typename T>
12274 static T sign(T t);
12276 template <typename T>
12277 static T smoothStep(T e0, T e1, T val);
12279 template <typename T>
12280 static T step(T edge, T val);
12282 template <typename T, int Rows, int Cols>
12283 static tcu::Matrix<T, Cols, Rows> transpose(const tcu::Matrix<T, Rows, Cols>& matrix);
12285 template <typename T>
12286 static T trunc(T t);
12288 static tcu::UVec2 unpackDouble2x32(const glw::GLdouble& val);
12290 template <typename T>
12291 static T clamp(T x, T minVal, T maxVal)
12293 return min(max(x, minVal), maxVal);
12296 template <int Size>
12297 static tcu::Matrix<glw::GLdouble, Size, Size> cofactors(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix)
12299 tcu::Matrix<glw::GLdouble, Size, Size> result;
12301 for (glw::GLuint c = 0; c < Size; ++c)
12303 for (glw::GLuint r = 0; r < Size; ++r)
12305 const glw::GLdouble minor_value = minor_impl(matrix, c, r);
12307 result(r, c) = (1 == (c + r) % 2) ? -minor_value : minor_value;
12314 template <int Size>
12315 static tcu::Vector<glw::GLuint, Size> convertBvecToUvec(const tcu::Vector<bool, Size>& src)
12317 tcu::Vector<glw::GLuint, Size> result;
12319 for (glw::GLint i = 0; i < Size; ++i)
12321 if (GL_FALSE != src[i])
12334 template <typename T>
12335 static T det2(T _00, T _10, T _01, T _11)
12337 return _00 * _11 - _01 * _10;
12340 template <typename T>
12341 static T det3(T _00, T _10, T _20, T _01, T _11, T _21, T _02, T _12, T _22)
12343 return _00 * det2(_11, _21, _12, _22) - _10 * det2(_01, _21, _02, _22) + _20 * det2(_01, _11, _02, _12);
12346 template <typename T>
12347 static T det4(T _00, T _10, T _20, T _30, T _01, T _11, T _21, T _31, T _02, T _12, T _22, T _32, T _03, T _13, T _23,
12350 return _00 * det3(_11, _21, _31, _12, _22, _32, _13, _23, _33) -
12351 _10 * det3(_01, _21, _31, _02, _22, _32, _03, _23, _33) +
12352 _20 * det3(_01, _11, _31, _02, _12, _32, _03, _13, _33) -
12353 _30 * det3(_01, _11, _21, _02, _12, _22, _03, _13, _23);
12356 template <typename T>
12357 static T determinant(T val)
12362 template <typename T>
12363 static T determinant(const tcu::Matrix<T, 2, 2>& mat)
12365 return det2(mat(0, 0), mat(0, 1), mat(1, 0), mat(1, 1));
12368 template <typename T>
12369 static T determinant(const tcu::Matrix<T, 3, 3>& mat)
12371 return det3(mat(0, 0), mat(0, 1), mat(0, 2), mat(1, 0), mat(1, 1), mat(1, 2), mat(2, 0), mat(2, 1), mat(2, 2));
12374 template <typename T>
12375 static T determinant(const tcu::Matrix<T, 4, 4>& mat)
12377 return det4(mat(0, 0), mat(0, 1), mat(0, 2), mat(0, 3), mat(1, 0), mat(1, 1), mat(1, 2), mat(1, 3), mat(2, 0),
12378 mat(2, 1), mat(2, 2), mat(2, 3), mat(3, 0), mat(3, 1), mat(3, 2), mat(3, 3));
12381 template <int Size>
12382 static tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminate(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix,
12383 glw::GLuint column, glw::GLuint row)
12385 tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> result;
12387 for (glw::GLuint c = 0; c < Size; ++c)
12389 /* Skip eliminated column */
12395 for (glw::GLuint r = 0; r < Size; ++r)
12397 /* Skip eliminated row */
12403 const glw::GLint r_offset = (r > row) ? -1 : 0;
12404 const glw::GLint c_offset = (c > column) ? -1 : 0;
12406 result(r + r_offset, c + c_offset) = matrix(r, c);
12413 template <int Size>
12414 static tcu::Vector<glw::GLuint, Size> equal(const tcu::Vector<glw::GLdouble, Size>& left,
12415 const tcu::Vector<glw::GLdouble, Size>& right)
12417 return convertBvecToUvec(tcu::equal(left, right));
12420 static glw::GLdouble fma(glw::GLdouble a, glw::GLdouble b, glw::GLdouble c)
12425 static glw::GLdouble fract(glw::GLdouble val)
12427 return val - floor(val);
12430 template <typename T>
12431 static T frexp(T val, glw::GLint& exp)
12433 return ::frexp(val, &exp);
12436 template <int Size>
12437 static tcu::Vector<glw::GLuint, Size> greaterThan(const tcu::Vector<glw::GLdouble, Size>& left,
12438 const tcu::Vector<glw::GLdouble, Size>& right)
12440 return convertBvecToUvec(tcu::greaterThan(left, right));
12443 template <int Size>
12444 static tcu::Vector<glw::GLuint, Size> greaterThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12445 const tcu::Vector<glw::GLdouble, Size>& right)
12447 return convertBvecToUvec(tcu::greaterThanEqual(left, right));
12450 template <int Size>
12451 static tcu::Matrix<glw::GLdouble, Size, Size> inverse(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix)
12453 const tcu::Matrix<glw::GLdouble, Size, Size> cof = cofactors(matrix);
12454 const tcu::Matrix<glw::GLdouble, Size, Size> adjugate = tcu::transpose(cof);
12455 const glw::GLdouble det = determinant(matrix);
12456 const glw::GLdouble inv_det = 1.0 / det;
12458 tcu::Matrix<glw::GLdouble, Size, Size> result = adjugate * inv_det;
12463 static glw::GLdouble inverseSqrt(glw::GLdouble val)
12465 const glw::GLdouble root = sqrt(val);
12467 return (1.0 / root);
12470 static glw::GLuint isinf_impl(glw::GLdouble val)
12472 const glw::GLdouble infinity = std::numeric_limits<glw::GLdouble>::infinity();
12474 return ((infinity == val) || (-infinity == val));
12477 static glw::GLuint isnan_impl(glw::GLdouble val)
12482 template <typename T>
12483 static T ldexp(T val, glw::GLint exp)
12485 return ::ldexp(val, exp);
12488 template <int Size>
12489 static tcu::Vector<glw::GLuint, Size> lessThan(const tcu::Vector<glw::GLdouble, Size>& left,
12490 const tcu::Vector<glw::GLdouble, Size>& right)
12492 return convertBvecToUvec(tcu::lessThan(left, right));
12495 template <int Size>
12496 static tcu::Vector<glw::GLuint, Size> lessThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12497 const tcu::Vector<glw::GLdouble, Size>& right)
12499 return convertBvecToUvec(tcu::lessThanEqual(left, right));
12502 template <typename T>
12503 static T max(T left, T right)
12505 return (left >= right) ? left : right;
12508 template <typename T>
12509 static T min(T left, T right)
12511 return (left <= right) ? left : right;
12514 template <int Size>
12515 static glw::GLdouble minor_impl(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix, glw::GLuint column,
12518 tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminated = eliminate(matrix, column, row);
12520 return determinant(eliminated);
12524 glw::GLdouble minor_impl<2>(const tcu::Matrix<glw::GLdouble, 2, 2>& matrix, glw::GLuint column, glw::GLuint row)
12526 const glw::GLuint r = (0 == row) ? 1 : 0;
12527 const glw::GLuint c = (0 == column) ? 1 : 0;
12529 return matrix(r, c);
12532 template <typename T>
12533 static T mix(T left, T right, T weight)
12535 return left * (1 - weight) + right * (weight);
12538 template <typename T>
12539 static T mod(T left, T right)
12541 const T div_res = left / right;
12542 const T floored = floor(div_res);
12544 return left - right * floored;
12547 template <typename T>
12548 static T modf(T val, T& integer)
12550 return ::modf(val, &integer);
12553 template <typename T>
12554 static T multiply(T left, T right)
12556 T result = left * right;
12561 template <int Size>
12562 static tcu::Vector<glw::GLuint, Size> notEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12563 const tcu::Vector<glw::GLdouble, Size>& right)
12565 return convertBvecToUvec(tcu::notEqual(left, right));
12568 template <int Cols, int Rows>
12569 static tcu::Matrix<glw::GLdouble, Rows, Cols> outerProduct(const tcu::Vector<glw::GLdouble, Rows>& left,
12570 const tcu::Vector<glw::GLdouble, Cols>& right)
12572 tcu::Matrix<glw::GLdouble, Rows, 1> left_mat;
12573 tcu::Matrix<glw::GLdouble, 1, Cols> right_mat;
12574 tcu::Matrix<glw::GLdouble, Rows, Cols> result;
12576 for (glw::GLuint i = 0; i < Rows; ++i)
12578 left_mat(i, 0) = left[i];
12581 for (glw::GLuint i = 0; i < Cols; ++i)
12583 right_mat(0, i) = right[i];
12586 result = left_mat * right_mat;
12591 static glw::GLdouble packDouble2x32(const tcu::UVec2& in)
12593 const glw::GLuint buffer[2] = { in[0], in[1] };
12594 glw::GLdouble result;
12595 memcpy(&result, buffer, sizeof(result));
12599 template <typename T>
12600 static T round(T t)
12605 if (((T)0.5) < frac)
12613 template <typename T>
12614 static T roundEven(T t)
12619 if (((T)0.5) < frac)
12623 else if ((((T)0.5) == frac) && (0 != ((int)res) % 2))
12631 template <typename T>
12648 template <typename T>
12649 static T smoothStep(T e0, T e1, T val)
12661 T temp = (val - e0) / (e1 - e0);
12663 T result = temp * temp * (3 - 2 * temp);
12668 template <typename T>
12669 static T step(T edge, T val)
12681 template <typename T, int Rows, int Cols>
12682 static tcu::Matrix<T, Cols, Rows> transpose(const tcu::Matrix<T, Rows, Cols>& matrix)
12684 tcu::Matrix<T, Cols, Rows> result = tcu::transpose(matrix);
12689 template <typename T>
12690 static T trunc(T t)
12692 const T abs_value = de::abs(t);
12693 const T result_value = floor(abs_value);
12695 const T result = sign(t) * result_value;
12700 static tcu::UVec2 unpackDouble2x32(const glw::GLdouble& val)
12702 glw::GLuint* ptr = (glw::GLuint*)&val;
12703 tcu::UVec2 result(ptr[0], ptr[1]);
12709 /** Enumeration of tested functions
12710 * *_AGAINT_SCALAR enums are used to call glsl function with mixed scalar and genDType arguments.
12711 * For example "max" can be called for (dvec3, double).
12718 FUNCTION_CLAMP_AGAINST_SCALAR,
12720 FUNCTION_DETERMINANT,
12724 FUNCTION_FACEFORWARD,
12729 FUNCTION_GREATERTHAN,
12730 FUNCTION_GREATERTHANEQUAL,
12732 FUNCTION_INVERSESQRT,
12735 FUNCTION_LESSTHANEQUAL,
12737 FUNCTION_MATRIXCOMPMULT,
12739 FUNCTION_MAX_AGAINST_SCALAR,
12741 FUNCTION_MIN_AGAINST_SCALAR,
12744 FUNCTION_MOD_AGAINST_SCALAR,
12746 FUNCTION_NORMALIZE,
12748 FUNCTION_OUTERPRODUCT,
12749 FUNCTION_PACKDOUBLE2X32,
12753 FUNCTION_ROUNDEVEN,
12755 FUNCTION_SMOOTHSTEP,
12756 FUNCTION_SMOOTHSTEP_AGAINST_SCALAR,
12759 FUNCTION_STEP_AGAINST_SCALAR,
12760 FUNCTION_TRANSPOSE,
12762 FUNCTION_UNPACKDOUBLE2X32,
12767 struct TypeDefinition
12770 glw::GLuint n_columns;
12771 glw::GLuint n_rows;
12774 /** Implementation of BuiltinFunctionTest test, description follows:
12776 * Verify double-precision support in common functions works correctly.
12777 * All double-precision types that apply for particular cases should
12778 * be tested for the following functions:
12794 * - greaterThanEqual();
12799 * - lessThanEqual();
12801 * - matrixCompMult();
12809 * - outerProduct();
12810 * - packDouble2x32();
12821 * - unpackDouble2x32();
12825 * The test should work by creating a program object (for each case
12826 * considered), to which a vertex shader should be attached. The
12827 * shader should define input variables that should be used as
12828 * arguments for the function in question. The result of the
12829 * operation should then be XFBed back to the test, where the
12830 * value should be verified.
12832 * Reference function implementation from pre-DEQP CTS framework
12833 * should be ported to C for verification purposes where available.
12835 * The test should use 1024 different scalar/vector/matrix argument
12836 * combinations. It should pass if all functions are determined
12837 * to work correctly for all argument combinations used.
12839 class BuiltinFunctionTest : public deqp::TestCase
12842 /* Public methods */
12843 BuiltinFunctionTest(deqp::Context& context, std::string caseName, FunctionEnum function,
12844 TypeDefinition typeDefinition);
12846 virtual void deinit();
12847 virtual tcu::TestNode::IterateResult iterate();
12849 /** Base class of functionObject. Main goal of it is to keep function details toghether and hide calling code.
12852 class functionObject
12855 functionObject(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
12856 Utils::_variable_type result_type);
12858 virtual ~functionObject()
12862 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const = 0;
12864 virtual glw::GLuint getArgumentCount() const = 0;
12865 virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const = 0;
12866 glw::GLuint getArgumentComponents(glw::GLuint argument) const;
12867 glw::GLuint getArgumentComponentSize(glw::GLuint argument) const;
12868 glw::GLuint getArgumentOffset(glw::GLuint argument) const;
12869 glw::GLuint getArgumentStride() const;
12870 glw::GLuint getArgumentStride(glw::GLuint argument) const;
12871 FunctionEnum getFunctionEnum() const;
12872 const glw::GLchar* getName() const;
12873 glw::GLuint getResultComponents(glw::GLuint result) const;
12874 virtual glw::GLuint getResultCount() const;
12875 glw::GLuint getResultOffset(glw::GLuint result) const;
12876 virtual Utils::_variable_type getResultType(glw::GLuint result) const;
12877 glw::GLuint getResultStride(glw::GLuint result) const;
12878 glw::GLuint getBaseTypeSize(glw::GLuint result) const;
12879 glw::GLuint getResultStride() const;
12882 const FunctionEnum m_function_enum;
12883 const glw::GLchar* m_function_name;
12884 const glw::GLvoid* m_p_function;
12885 const Utils::_variable_type m_res_type;
12889 /* Private types */
12890 /** General type enumeration
12900 /** Details of variable type
12905 typeDetails(glw::GLuint n_columns, glw::GLuint n_rows);
12907 generalType m_general_type;
12908 glw::GLuint m_n_columns;
12909 glw::GLuint m_n_rows;
12910 glw::GLenum m_type;
12911 std::string m_type_name;
12914 /* Typedefs for gl.uniform* function pointers */
12915 typedef GLW_APICALL void(GLW_APIENTRY* uniformDMatFunctionPointer)(glw::GLint, glw::GLsizei, glw::GLboolean,
12916 const glw::GLdouble*);
12917 typedef GLW_APICALL void(GLW_APIENTRY* uniformDVecFunctionPointer)(glw::GLint, glw::GLsizei, const glw::GLdouble*);
12918 typedef GLW_APICALL void(GLW_APIENTRY* uniformIVecFunctionPointer)(glw::GLint, glw::GLsizei, const glw::GLint*);
12919 typedef GLW_APICALL void(GLW_APIENTRY* uniformUVecFunctionPointer)(glw::GLint, glw::GLsizei, const glw::GLuint*);
12921 /* Private methods */
12922 bool compare(Utils::_variable_type type, const glw::GLvoid* left, const glw::GLvoid* right);
12924 functionObject* getFunctionObject(FunctionEnum function, const typeDetails& type);
12926 uniformDMatFunctionPointer getUniformFunctionForDMat(glw::GLuint argument,
12927 const functionObject& function_object) const;
12929 uniformDVecFunctionPointer getUniformFunctionForDVec(glw::GLuint argument,
12930 const functionObject& function_object) const;
12932 uniformIVecFunctionPointer getUniformFunctionForIVec(glw::GLuint argument,
12933 const functionObject& function_object) const;
12935 uniformUVecFunctionPointer getUniformFunctionForUVec(glw::GLuint argument,
12936 const functionObject& function_object) const;
12938 const glw::GLchar* getUniformName(glw::GLuint argument) const;
12939 const glw::GLchar* getVaryingName(glw::GLuint argument) const;
12941 bool isFunctionImplemented(FunctionEnum function, const typeDetails& type) const;
12943 void logVariableType(const glw::GLvoid* buffer, const glw::GLchar* name, Utils::_variable_type type) const;
12945 void prepareArgument(const functionObject& function_object, glw::GLuint vertex, glw::GLubyte* buffer);
12947 void prepareComponents(const functionObject& function_object, glw::GLuint vertex, glw::GLuint argument,
12948 glw::GLubyte* buffer);
12950 void prepareProgram(const functionObject& function_object, Utils::programInfo& program_info);
12952 void prepareTestData(const functionObject& function_object);
12953 void prepareVertexShaderCode(const functionObject& function_object);
12955 bool test(FunctionEnum function, const typeDetails& type);
12957 void testBegin(const functionObject& function_object, glw::GLuint program_id, glw::GLuint vertex);
12961 bool verifyResults(const functionObject& function_object, glw::GLuint vertex);
12963 /* Private constants */
12964 static const glw::GLdouble m_epsilon;
12965 static const glw::GLuint m_n_veritces;
12967 /* Private fields */
12968 glw::GLuint m_transform_feedback_buffer_id;
12969 glw::GLuint m_vertex_array_object_id;
12971 std::vector<glw::GLubyte> m_expected_results_data;
12972 FunctionEnum m_function;
12973 TypeDefinition m_typeDefinition;
12974 std::vector<glw::GLubyte> m_argument_data;
12975 std::string m_vertex_shader_code;
12978 /* Constants used by BuiltinFunctionTest */
12979 /** Khronos Bug #14010
12980 * Using an epsilon value for comparing floating points is error prone.
12981 * Rather than writing a new floating point comparison function, I am
12982 * increasing the epsilon value to allow greater orders of magnitude
12983 * of floating point values.
12985 const glw::GLdouble BuiltinFunctionTest::m_epsilon = 0.00002;
12986 const glw::GLuint BuiltinFunctionTest::m_n_veritces = 1024;
12988 /** Implementations of function objects required by "BuiltinFunctionTest"
12991 namespace FunctionObject
12993 /** Maps variable type with enumeration Utils::_variable_type
12997 template <typename T>
13001 static const Utils::_variable_type variable_type =
13002 TypeHelpers::typeInfo<typename TypeHelpers::referenceToType<T>::result>::variable_type;
13005 /** Place data from <in> into <buffer>
13007 * @param buffer Buffer
13008 * @param in Input data
13010 template <typename T>
13014 static void set(glw::GLvoid* buffer, const T& in)
13020 /** Place tcu::Matrix data from <in> into <buffer>
13022 * @param buffer Buffer
13023 * @param in Input data
13025 template <int Cols, int Rows>
13026 class pack<tcu::Matrix<glw::GLdouble, Rows, Cols> >
13029 static void set(glw::GLvoid* buffer, const tcu::Matrix<glw::GLdouble, Rows, Cols>& in)
13031 glw::GLdouble* data = (glw::GLdouble*)buffer;
13033 for (glw::GLint column = 0; column < Cols; ++column)
13035 for (glw::GLint row = 0; row < Rows; ++row)
13037 glw::GLint index = column * Rows + row;
13039 data[index] = in(row, column);
13045 /** Get data of <out> from <buffer>
13047 * @param buffer Buffer
13048 * @param out Output data
13050 template <typename T>
13054 static void get(const glw::GLvoid* buffer, T& out)
13060 /** Get tcu::Matrix data from <buffer>
13062 * @param buffer Buffer
13063 * @param out Output data
13065 template <int Cols, int Rows>
13066 class unpack<tcu::Matrix<glw::GLdouble, Rows, Cols> >
13069 static void get(const glw::GLvoid* buffer, tcu::Matrix<glw::GLdouble, Rows, Cols>& out)
13071 const glw::GLdouble* data = (glw::GLdouble*)buffer;
13073 for (glw::GLint column = 0; column < Cols; ++column)
13075 for (glw::GLint row = 0; row < Rows; ++row)
13077 glw::GLint index = column * Rows + row;
13079 out(row, column) = data[index];
13085 /** Base of unary function classes
13088 class unaryBase : public BuiltinFunctionTest::functionObject
13091 unaryBase(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
13092 const Utils::_variable_type res_type, const Utils::_variable_type arg_type)
13093 : functionObject(function_enum, function_name, function_pointer, res_type), m_arg_type(arg_type)
13097 virtual glw::GLuint getArgumentCount() const
13102 virtual Utils::_variable_type getArgumentType(glw::GLuint /* argument */) const
13108 const Utils::_variable_type m_arg_type;
13111 /** Unary function class. It treats input argument as one variable.
13113 * @tparam ResT Type of result
13114 * @tparam ArgT Type of argument
13116 template <typename ResT, typename ArgT>
13117 class unary : public unaryBase
13120 typedef ResT (*functionPointer)(const ArgT&);
13122 unary(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer)
13123 : unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
13124 typeInfo<ArgT>::variable_type)
13128 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
13133 unpack<ArgT>::get(argument_src, arg);
13135 functionPointer p_function = (functionPointer)m_p_function;
13137 result = p_function(arg);
13139 pack<ResT>::set(result_dst, result);
13143 /** Unary function class. It treats input argument as separate components.
13145 * @tparam ResT Type of result
13147 template <typename ResT>
13148 class unaryByComponent : public unaryBase
13151 typedef ResT (*functionPointer)(glw::GLdouble);
13153 unaryByComponent(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer,
13154 const Utils::_variable_type res_type, const Utils::_variable_type arg_type)
13155 : unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_type)
13159 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
13161 glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(m_arg_type);
13162 ResT* p_result = (ResT*)result_dst;
13163 glw::GLdouble* p_arg = (glw::GLdouble*)argument_src;
13165 functionPointer p_function = (functionPointer)m_p_function;
13167 for (glw::GLuint component = 0; component < n_components; ++component)
13169 p_result[component] = p_function(p_arg[component]);
13174 /** Class of functions with one input and one output parameter. It treats arguments as separate components.
13176 * @tparam ResT Type of result
13177 * @tparam ArgT Type of argument
13178 * @tparam OutT Type of output parameter
13180 template <typename ResT, typename ArgT, typename OutT>
13181 class unaryWithOutputByComponent : public unaryBase
13184 typedef ResT (*functionPointer)(ArgT, OutT&);
13186 unaryWithOutputByComponent(FunctionEnum function_enum, const glw::GLchar* function_name,
13187 functionPointer function_pointer, const Utils::_variable_type res_type,
13188 const Utils::_variable_type arg_type, const Utils::_variable_type out_type)
13189 : unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_type)
13190 , m_out_type(out_type)
13194 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
13196 ResT* p_result = (ResT*)result_dst;
13197 OutT* p_out = (OutT*)((glw::GLubyte*)result_dst + getResultOffset(1));
13198 ArgT* p_arg = (ArgT*)argument_src;
13200 const glw::GLuint n_components_0 = getArgumentComponents(0);
13201 const glw::GLuint n_components_1 = getResultComponents(1);
13202 const glw::GLuint n_components = de::max(n_components_0, n_components_1);
13204 const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
13205 const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;
13207 functionPointer p_function = (functionPointer)m_p_function;
13209 for (glw::GLuint component = 0; component < n_components; ++component)
13211 const ArgT first_arg = p_arg[component * component_step_0];
13212 OutT& second_arg = p_out[component * component_step_1];
13214 p_result[component] = p_function(first_arg, second_arg);
13218 glw::GLuint getResultCount() const
13223 Utils::_variable_type getResultType(glw::GLuint result) const
13225 Utils::_variable_type type = Utils::VARIABLE_TYPE_UNKNOWN;
13236 TCU_FAIL("Not implemented");
13244 const Utils::_variable_type m_out_type;
13247 /** Base of binary function classes.
13250 class binaryBase : public BuiltinFunctionTest::functionObject
13253 binaryBase(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
13254 const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
13255 const Utils::_variable_type arg_2_type)
13256 : functionObject(function_enum, function_name, function_pointer, res_type)
13257 , m_arg_1_type(arg_1_type)
13258 , m_arg_2_type(arg_2_type)
13262 virtual glw::GLuint getArgumentCount() const
13267 virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const
13272 return m_arg_1_type;
13275 return m_arg_2_type;
13278 return Utils::VARIABLE_TYPE_UNKNOWN;
13284 const Utils::_variable_type m_arg_1_type;
13285 const Utils::_variable_type m_arg_2_type;
13288 /** Binary function class. It treats input arguments as two variables.
13290 * @param ResT Type of result
13291 * @param Arg1T Type of first argument
13292 * @param Arg2T Type of second argument
13294 template <typename ResT, typename Arg1T, typename Arg2T>
13295 class binary : public binaryBase
13298 typedef ResT (*functionPointer)(const Arg1T&, const Arg2T&);
13300 binary(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer)
13301 : binaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
13302 typeInfo<Arg1T>::variable_type, typeInfo<Arg2T>::variable_type)
13306 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
13308 const glw::GLuint argument_1_stride = getArgumentStride(0);
13310 functionPointer p_function = (functionPointer)m_p_function;
13316 unpack<Arg1T>::get(argument_src, arg_1);
13317 unpack<Arg2T>::get((glw::GLubyte*)argument_src + argument_1_stride, arg_2);
13319 result = p_function(arg_1, arg_2);
13321 pack<ResT>::set(result_dst, result);
13325 /** Binary function class. It treats input arguments as separate components.
13327 * @param ResT Type of result
13328 * @param Arg1T Type of first argument
13329 * @param Arg2T Type of second argument
13331 template <typename ResT, typename Arg1T, typename Arg2T>
13332 class binaryByComponent : public binaryBase
13335 typedef ResT (*functionPointer)(Arg1T, Arg2T);
13337 binaryByComponent(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer,
13338 const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
13339 const Utils::_variable_type arg_2_type)
13340 : binaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_1_type, arg_2_type)
13344 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
13346 ResT* p_result = (ResT*)result_dst;
13347 Arg1T* p_arg_1 = (Arg1T*)argument_src;
13348 Arg2T* p_arg_2 = (Arg2T*)((glw::GLubyte*)argument_src + getArgumentOffset(1));
13350 const glw::GLuint n_components_0 = getArgumentComponents(0);
13351 const glw::GLuint n_components_1 = getArgumentComponents(1);
13352 const glw::GLuint n_components = de::max(n_components_0, n_components_1);
13354 const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
13355 const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;
13357 functionPointer p_function = (functionPointer)m_p_function;
13359 for (glw::GLuint component = 0; component < n_components; ++component)
13361 const Arg1T first_arg = p_arg_1[component * component_step_0];
13362 const Arg2T second_arg = p_arg_2[component * component_step_1];
13364 p_result[component] = p_function(first_arg, second_arg);
13369 /** Base of tenary function classes.
13372 class tenaryBase : public BuiltinFunctionTest::functionObject
13375 tenaryBase(FunctionEnum function_enum, const glw::GLchar* function_name, glw::GLvoid* function_pointer,
13376 const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
13377 const Utils::_variable_type arg_2_type, const Utils::_variable_type arg_3_type)
13378 : functionObject(function_enum, function_name, function_pointer, res_type)
13379 , m_arg_1_type(arg_1_type)
13380 , m_arg_2_type(arg_2_type)
13381 , m_arg_3_type(arg_3_type)
13385 virtual glw::GLuint getArgumentCount() const
13390 virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const
13395 return m_arg_1_type;
13398 return m_arg_2_type;
13401 return m_arg_3_type;
13404 return Utils::VARIABLE_TYPE_UNKNOWN;
13410 const Utils::_variable_type m_arg_1_type;
13411 const Utils::_variable_type m_arg_2_type;
13412 const Utils::_variable_type m_arg_3_type;
13415 /** Tenary function class. It treats input arguments as three variables.
13417 * @param ResT Type of result
13418 * @param Arg1T Type of first argument
13419 * @param Arg2T Type of second argument
13420 * @param Arg3T Type of third argument
13422 template <typename ResT, typename Arg1T, typename Arg2T, typename Arg3T>
13423 class tenary : public tenaryBase
13426 typedef ResT (*functionPointer)(Arg1T, Arg2T, Arg3T);
13427 typedef typename TypeHelpers::referenceToType<Arg1T>::result arg1T;
13428 typedef typename TypeHelpers::referenceToType<Arg2T>::result arg2T;
13429 typedef typename TypeHelpers::referenceToType<Arg3T>::result arg3T;
13431 tenary(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer)
13432 : tenaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
13433 typeInfo<Arg1T>::variable_type, typeInfo<Arg2T>::variable_type, typeInfo<Arg3T>::variable_type)
13437 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
13439 const glw::GLuint argument_2_offset = getArgumentOffset(1);
13440 const glw::GLuint argument_3_offset = getArgumentOffset(2);
13442 functionPointer p_function = (functionPointer)m_p_function;
13449 unpack<arg1T>::get(argument_src, arg_1);
13450 unpack<arg2T>::get((glw::GLubyte*)argument_src + argument_2_offset, arg_2);
13451 unpack<arg3T>::get((glw::GLubyte*)argument_src + argument_3_offset, arg_3);
13453 result = p_function(arg_1, arg_2, arg_3);
13455 pack<ResT>::set(result_dst, result);
13459 /** Tenary function class. It treats input arguments as separate components.
13463 class tenaryByComponent : public tenaryBase
13466 typedef glw::GLdouble (*functionPointer)(glw::GLdouble, glw::GLdouble, glw::GLdouble);
13468 tenaryByComponent(FunctionEnum function_enum, const glw::GLchar* function_name, functionPointer function_pointer,
13469 const Utils::_variable_type res_type, const Utils::_variable_type arg_1_type,
13470 const Utils::_variable_type arg_2_type, const Utils::_variable_type arg_3_type)
13471 : tenaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_1_type, arg_2_type,
13476 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
13478 glw::GLdouble* p_result = (glw::GLdouble*)result_dst;
13479 const glw::GLdouble* p_arg = (const glw::GLdouble*)argument_src;
13481 const glw::GLuint n_components_0 = getArgumentComponents(0);
13482 const glw::GLuint n_components_1 = getArgumentComponents(1);
13483 const glw::GLuint n_components_2 = getArgumentComponents(2);
13484 const glw::GLuint n_components = de::max(de::max(n_components_0, n_components_1), n_components_2);
13486 const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
13487 const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;
13488 const glw::GLuint component_step_2 = (1 == n_components_2) ? 0 : 1;
13490 functionPointer p_function = (functionPointer)m_p_function;
13492 for (glw::GLuint component = 0; component < n_components; ++component)
13494 const glw::GLdouble first_arg = p_arg[component * component_step_0];
13495 const glw::GLdouble second_arg = p_arg[component * component_step_1 + n_components_0];
13496 const glw::GLdouble third_arg = p_arg[component * component_step_2 + n_components_0 + n_components_1];
13498 p_result[component] = p_function(first_arg, second_arg, third_arg);
13502 } /* FunctionObject */
13506 * @param context Rendering context.
13508 BuiltinFunctionTest::BuiltinFunctionTest(deqp::Context& context, std::string caseName, FunctionEnum function,
13509 TypeDefinition typeDefinition)
13510 : TestCase(context, caseName.c_str(), "Verify that built-in functions support double-precision types")
13511 , m_transform_feedback_buffer_id(0)
13512 , m_vertex_array_object_id(0)
13513 , m_function(function)
13514 , m_typeDefinition(typeDefinition)
13516 /* Nothing to be done here */
13519 /** Deinitializes all GL objects that may have been created during test execution.
13522 void BuiltinFunctionTest::deinit()
13524 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13526 /* Clean buffers */
13527 if (0 != m_transform_feedback_buffer_id)
13529 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
13530 gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
13531 m_transform_feedback_buffer_id = 0;
13535 if (0 != m_vertex_array_object_id)
13537 gl.bindVertexArray(0);
13538 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
13539 m_vertex_array_object_id = 0;
13545 * @return tcu::TestNode::STOP
13547 tcu::TestNode::IterateResult BuiltinFunctionTest::iterate()
13549 /* Check if extension is supported */
13550 if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
13552 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
13557 /* Verify result */
13558 typeDetails type(m_typeDefinition.n_columns, m_typeDefinition.n_rows);
13559 if (test(m_function, type))
13561 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
13565 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13569 return tcu::TestNode::STOP;
13574 * @param function_enum Function enumeration
13575 * @param function_name Function name
13576 * @param function_pointer Pointer to routine that wiil be executed
13577 * @param result_type Type of result
13579 BuiltinFunctionTest::functionObject::functionObject(FunctionEnum function_enum, const glw::GLchar* function_name,
13580 glw::GLvoid* function_pointer, Utils::_variable_type result_type)
13581 : m_function_enum(function_enum)
13582 , m_function_name(function_name)
13583 , m_p_function(function_pointer)
13584 , m_res_type(result_type)
13586 /* Nothing to be done here */
13589 /** Get number of components for <argument>
13591 * @param argument Argument ordinal, starts with 0
13593 * @return Number of components
13595 glw::GLuint BuiltinFunctionTest::functionObject::getArgumentComponents(glw::GLuint argument) const
13597 const Utils::_variable_type type = getArgumentType(argument);
13598 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13600 return n_components;
13603 /** Get size in bytes of single component of <argument>
13605 * @param argument Argument ordinal, starts with 0
13607 * @return Size of component
13609 glw::GLuint BuiltinFunctionTest::functionObject::getArgumentComponentSize(glw::GLuint argument) const
13611 const Utils::_variable_type type = getArgumentType(argument);
13612 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
13613 const glw::GLuint base_type_size = Utils::getBaseVariableTypeComponentSize(base_type);
13615 return base_type_size;
13618 /** Get offset in bytes of <argument>. 0 is offset of first argument. Assumes tight packing.
13620 * @param argument Argument ordinal, starts with 0
13622 * @return Offset of arguemnt's data
13624 glw::GLuint BuiltinFunctionTest::functionObject::getArgumentOffset(glw::GLuint argument) const
13626 glw::GLuint result = 0;
13628 for (glw::GLuint i = 0; i < argument; ++i)
13630 result += getArgumentStride(i);
13636 /** Get stride in bytes of all arguments
13638 * @return Stride of all arguments
13640 glw::GLuint BuiltinFunctionTest::functionObject::getArgumentStride() const
13642 const glw::GLuint n_args = getArgumentCount();
13643 glw::GLuint result = 0;
13645 for (glw::GLuint i = 0; i < n_args; ++i)
13647 result += getArgumentStride(i);
13653 /** Get stride in bytes of <argument>
13655 * @param argument Argument ordinal, starts with 0
13657 * @return Stride of argument
13659 glw::GLuint BuiltinFunctionTest::functionObject::getArgumentStride(glw::GLuint argument) const
13661 const glw::GLuint component_size = getArgumentComponentSize(argument);
13662 const glw::GLuint n_components = getArgumentComponents(argument);
13664 return n_components * component_size;
13667 /** Get function enumeration
13669 * @return Function enumeration
13671 FunctionEnum BuiltinFunctionTest::functionObject::getFunctionEnum() const
13673 return m_function_enum;
13676 /** Get function name
13678 * @return Function name
13680 const glw::GLchar* BuiltinFunctionTest::functionObject::getName() const
13682 return m_function_name;
13685 /** Get number of components for <result>
13687 * @param result Result ordinal, starts with 0
13689 * @return Number of components
13691 glw::GLuint BuiltinFunctionTest::functionObject::getResultComponents(glw::GLuint result) const
13693 const Utils::_variable_type type = getResultType(result);
13694 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13696 return n_components;
13699 /** Get number of results
13701 * @return Number of results
13703 glw::GLuint BuiltinFunctionTest::functionObject::getResultCount() const
13708 /** Get offset in bytes of <result>. First result offset is 0. Assume tight packing.
13710 * @param result Result ordinal, starts with 0
13714 glw::GLuint BuiltinFunctionTest::functionObject::getResultOffset(glw::GLuint result) const
13716 glw::GLuint offset = 0;
13718 for (glw::GLuint i = 0; i < result; ++i)
13720 offset += getResultStride(i);
13721 offset = deAlign32(offset, getBaseTypeSize(i));
13727 /** Get stride in bytes of <result>.
13729 * @param result Result ordinal, starts with 0
13733 glw::GLuint BuiltinFunctionTest::functionObject::getResultStride(glw::GLuint result) const
13735 const Utils::_variable_type type = getResultType(result);
13736 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13738 return n_components * getBaseTypeSize(result);
13741 /** Get size in bytes of <result> base component.
13743 * @param result Result ordinal, starts with 0
13745 * @return Alignment
13747 glw::GLuint BuiltinFunctionTest::functionObject::getBaseTypeSize(glw::GLuint result) const
13749 const Utils::_variable_type type = getResultType(result);
13750 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
13751 const glw::GLuint base_type_size = Utils::getBaseVariableTypeComponentSize(base_type);
13753 return base_type_size;
13756 /** Get stride in bytes of all results.
13760 glw::GLuint BuiltinFunctionTest::functionObject::getResultStride() const
13762 const glw::GLuint n_results = getResultCount();
13763 glw::GLuint stride = 0;
13764 glw::GLuint maxAlignment = 0;
13766 for (glw::GLuint i = 0; i < n_results; ++i)
13768 const glw::GLuint alignment = getBaseTypeSize(i);
13769 stride += getResultStride(i);
13770 stride = deAlign32(stride, alignment);
13771 maxAlignment = deMaxu32(maxAlignment, alignment);
13774 // The stride of all results must also be aligned,
13775 // so results for next vertex are aligned.
13776 return deAlign32(stride, maxAlignment);
13779 /** Get type of <result>.
13781 * @param result Result ordinal, starts with 0
13785 Utils::_variable_type BuiltinFunctionTest::functionObject::getResultType(glw::GLuint /* result */) const
13792 * @param n_columns Number of columns
13793 * @param n_rows Number of rows
13795 BuiltinFunctionTest::typeDetails::typeDetails(glw::GLuint n_columns, glw::GLuint n_rows)
13796 : m_n_columns(n_columns), m_n_rows(n_rows)
13798 Utils::_variable_type type = Utils::getDoubleVariableType(n_columns, n_rows);
13799 m_type = Utils::getGLDataTypeOfVariableType(type);
13800 m_type_name = Utils::getVariableTypeString(type);
13802 if (1 == m_n_columns)
13806 m_general_type = SCALAR;
13810 m_general_type = VECTOR;
13815 m_general_type = MATRIX;
13819 /** Compare two values
13821 * @param type Type of values
13822 * @param left Pointer to left value
13823 * @param right Pointer to right value
13825 * @return true if values are equal, false otherwise
13827 bool BuiltinFunctionTest::compare(Utils::_variable_type type, const glw::GLvoid* left, const glw::GLvoid* right)
13829 bool result = true;
13831 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13832 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
13836 case Utils::VARIABLE_TYPE_DOUBLE:
13839 const glw::GLdouble* left_values = (glw::GLdouble*)left;
13840 const glw::GLdouble* right_values = (glw::GLdouble*)right;
13842 for (glw::GLuint component = 0; component < n_components; ++component)
13844 const glw::GLdouble left_value = left_values[component];
13845 const glw::GLdouble right_value = right_values[component];
13847 if ((left_value != right_value) && (m_epsilon < de::abs(left_value - right_value)) &&
13848 (0 == Math::isnan_impl(left_value)) && (0 == Math::isnan_impl(right_value)))
13858 case Utils::VARIABLE_TYPE_INT:
13861 const glw::GLint* left_values = (glw::GLint*)left;
13862 const glw::GLint* right_values = (glw::GLint*)right;
13864 for (glw::GLuint component = 0; component < n_components; ++component)
13866 const glw::GLint left_value = left_values[component];
13867 const glw::GLint right_value = right_values[component];
13869 if (left_value != right_value)
13879 case Utils::VARIABLE_TYPE_UINT:
13882 const glw::GLuint* left_values = (glw::GLuint*)left;
13883 const glw::GLuint* right_values = (glw::GLuint*)right;
13885 for (glw::GLuint component = 0; component < n_components; ++component)
13887 const glw::GLuint left_value = left_values[component];
13888 const glw::GLuint right_value = right_values[component];
13890 if (left_value != right_value)
13902 TCU_FAIL("Not implemented");
13910 /** Create instance of function object for given function enumeration and type
13912 * @param function Function enumeration
13913 * @param type Type details
13915 * @return Create object
13917 BuiltinFunctionTest::functionObject* BuiltinFunctionTest::getFunctionObject(FunctionEnum function,
13918 const typeDetails& type)
13920 typedef tcu::Matrix<glw::GLdouble, 2, 2> DMat2;
13921 typedef tcu::Matrix<glw::GLdouble, 3, 2> DMat2x3;
13922 typedef tcu::Matrix<glw::GLdouble, 4, 2> DMat2x4;
13923 typedef tcu::Matrix<glw::GLdouble, 2, 3> DMat3x2;
13924 typedef tcu::Matrix<glw::GLdouble, 3, 3> DMat3;
13925 typedef tcu::Matrix<glw::GLdouble, 4, 3> DMat3x4;
13926 typedef tcu::Matrix<glw::GLdouble, 2, 4> DMat4x2;
13927 typedef tcu::Matrix<glw::GLdouble, 3, 4> DMat4x3;
13928 typedef tcu::Matrix<glw::GLdouble, 4, 4> DMat4;
13930 const glw::GLuint n_columns = type.m_n_columns;
13931 const glw::GLuint n_rows = type.m_n_rows;
13932 const Utils::_variable_type scalar_type = Utils::getDoubleVariableType(1, 1);
13933 const Utils::_variable_type variable_type = Utils::getDoubleVariableType(n_columns, n_rows);
13934 const Utils::_variable_type uint_type = Utils::getUintVariableType(1, n_rows);
13935 const Utils::_variable_type int_type = Utils::getIntVariableType(1, n_rows);
13941 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
13942 function, "abs", de::abs, variable_type /* res_type */, variable_type /* arg_type */);
13946 case FUNCTION_CEIL:
13948 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
13949 function, "ceil", ceil, variable_type /* res_type */, variable_type /* arg_type */);
13953 case FUNCTION_CLAMP:
13955 return new FunctionObject::tenaryByComponent(function, "clamp", Math::clamp, variable_type /* res_type */,
13956 variable_type /* arg1_type */, variable_type /* arg2_type */,
13957 variable_type /* arg3_type */);
13960 case FUNCTION_CLAMP_AGAINST_SCALAR:
13962 return new FunctionObject::tenaryByComponent(function, "clamp", Math::clamp, variable_type /* res_type */,
13963 variable_type /* arg1_type */, scalar_type /* arg2_type */,
13964 scalar_type /* arg3_type */);
13967 case FUNCTION_CROSS:
13969 return new FunctionObject::binary<tcu::DVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13970 function, "cross", tcu::cross);
13974 case FUNCTION_DETERMINANT:
13976 switch (variable_type)
13978 case Utils::VARIABLE_TYPE_DMAT2:
13979 return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat2 /* ArgT */>(function, "determinant",
13980 Math::determinant);
13981 case Utils::VARIABLE_TYPE_DMAT3:
13982 return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat3 /* ArgT */>(function, "determinant",
13983 Math::determinant);
13984 case Utils::VARIABLE_TYPE_DMAT4:
13985 return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat4 /* ArgT */>(function, "determinant",
13986 Math::determinant);
13988 TCU_FAIL("Not implemented");
13994 case FUNCTION_DISTANCE:
13996 switch (variable_type)
13998 case Utils::VARIABLE_TYPE_DVEC2:
13999 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14000 function, "distance", tcu::distance);
14002 case Utils::VARIABLE_TYPE_DVEC3:
14003 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14004 function, "distance", tcu::distance);
14006 case Utils::VARIABLE_TYPE_DVEC4:
14007 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14008 function, "distance", tcu::distance);
14018 switch (variable_type)
14020 case Utils::VARIABLE_TYPE_DVEC2:
14021 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14022 function, "dot", tcu::dot);
14024 case Utils::VARIABLE_TYPE_DVEC3:
14025 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14026 function, "dot", tcu::dot);
14028 case Utils::VARIABLE_TYPE_DVEC4:
14029 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14030 function, "dot", tcu::dot);
14038 case FUNCTION_EQUAL:
14040 switch (variable_type)
14042 case Utils::VARIABLE_TYPE_DVEC2:
14043 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14044 function, "equal", Math::equal);
14046 case Utils::VARIABLE_TYPE_DVEC3:
14047 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14048 function, "equal", Math::equal);
14050 case Utils::VARIABLE_TYPE_DVEC4:
14051 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14052 function, "equal", Math::equal);
14060 case FUNCTION_FACEFORWARD:
14062 switch (variable_type)
14064 case Utils::VARIABLE_TYPE_DVEC2:
14065 return new FunctionObject::tenary<tcu::DVec2 /* ResT */, const tcu::DVec2& /* Arg1T */,
14066 const tcu::DVec2& /* Arg2T */, const tcu::DVec2& /* Arg3T */>(
14067 function, "faceforward", tcu::faceForward);
14069 case Utils::VARIABLE_TYPE_DVEC3:
14070 return new FunctionObject::tenary<tcu::DVec3 /* ResT */, const tcu::DVec3& /* Arg1T */,
14071 const tcu::DVec3& /* Arg2T */, const tcu::DVec3& /* Arg3T */>(
14072 function, "faceforward", tcu::faceForward);
14074 case Utils::VARIABLE_TYPE_DVEC4:
14075 return new FunctionObject::tenary<tcu::DVec4 /* ResT */, const tcu::DVec4& /* Arg1T */,
14076 const tcu::DVec4& /* Arg2T */, const tcu::DVec4& /* Arg3T */>(
14077 function, "faceforward", tcu::faceForward);
14085 case FUNCTION_FLOOR:
14087 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14088 function, "floor", floor, variable_type /* res_type */, variable_type /* arg_type */);
14094 return new FunctionObject::tenaryByComponent(function, "fma", Math::fma, variable_type /* res_type */,
14095 variable_type /* arg1_type */, variable_type /* arg2_type */,
14096 variable_type /* arg3_type */);
14100 case FUNCTION_FRACT:
14102 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14103 function, "fract", Math::fract, variable_type /* res_type */, variable_type /* arg_type */);
14107 case FUNCTION_FREXP:
14109 return new FunctionObject::unaryWithOutputByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* ArgT */,
14110 glw::GLint /* OutT */>(
14111 function, "frexp", Math::frexp, variable_type /* res_type */, variable_type /* arg_type */,
14112 int_type /* out_type */);
14116 case FUNCTION_GREATERTHAN:
14118 switch (variable_type)
14120 case Utils::VARIABLE_TYPE_DVEC2:
14121 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14122 function, "greaterThan", Math::greaterThan);
14124 case Utils::VARIABLE_TYPE_DVEC3:
14125 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14126 function, "greaterThan", Math::greaterThan);
14128 case Utils::VARIABLE_TYPE_DVEC4:
14129 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14130 function, "greaterThan", Math::greaterThan);
14138 case FUNCTION_GREATERTHANEQUAL:
14140 switch (variable_type)
14142 case Utils::VARIABLE_TYPE_DVEC2:
14143 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14144 function, "greaterThanEqual", Math::greaterThanEqual);
14146 case Utils::VARIABLE_TYPE_DVEC3:
14147 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14148 function, "greaterThanEqual", Math::greaterThanEqual);
14150 case Utils::VARIABLE_TYPE_DVEC4:
14151 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14152 function, "greaterThanEqual", Math::greaterThanEqual);
14160 case FUNCTION_INVERSE:
14162 switch (variable_type)
14164 case Utils::VARIABLE_TYPE_DMAT2:
14165 return new FunctionObject::unary<DMat2 /* ResT */, DMat2 /* ArgT */>(function, "inverse", Math::inverse);
14167 case Utils::VARIABLE_TYPE_DMAT3:
14168 return new FunctionObject::unary<DMat3 /* ResT */, DMat3 /* ArgT */>(function, "inverse", Math::inverse);
14170 case Utils::VARIABLE_TYPE_DMAT4:
14171 return new FunctionObject::unary<DMat4 /* ResT */, DMat4 /* ArgT */>(function, "inverse", Math::inverse);
14179 case FUNCTION_INVERSESQRT:
14181 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14182 function, "inversesqrt", Math::inverseSqrt, variable_type /* res_type */, variable_type /* arg_type */);
14186 case FUNCTION_LDEXP:
14188 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14189 glw::GLint /* Arg2T */>(
14190 function, "ldexp", ::ldexp, variable_type /* res_type */, variable_type /* arg1_type */,
14191 int_type /* arg2_type */);
14195 case FUNCTION_LESSTHAN:
14197 switch (variable_type)
14199 case Utils::VARIABLE_TYPE_DVEC2:
14200 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14201 function, "lessThan", Math::lessThan);
14203 case Utils::VARIABLE_TYPE_DVEC3:
14204 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14205 function, "lessThan", Math::lessThan);
14207 case Utils::VARIABLE_TYPE_DVEC4:
14208 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14209 function, "lessThan", Math::lessThan);
14217 case FUNCTION_LESSTHANEQUAL:
14219 switch (variable_type)
14221 case Utils::VARIABLE_TYPE_DVEC2:
14222 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14223 function, "lessThanEqual", Math::lessThanEqual);
14225 case Utils::VARIABLE_TYPE_DVEC3:
14226 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14227 function, "lessThanEqual", Math::lessThanEqual);
14229 case Utils::VARIABLE_TYPE_DVEC4:
14230 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14231 function, "lessThanEqual", Math::lessThanEqual);
14239 case FUNCTION_LENGTH:
14241 switch (variable_type)
14243 case Utils::VARIABLE_TYPE_DVEC2:
14244 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec2 /* ArgT */>(function, "length",
14247 case Utils::VARIABLE_TYPE_DVEC3:
14248 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec3 /* ArgT */>(function, "length",
14251 case Utils::VARIABLE_TYPE_DVEC4:
14252 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec4 /* ArgT */>(function, "length",
14261 case FUNCTION_MATRIXCOMPMULT:
14263 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14264 glw::GLdouble /* Arg2T */>(
14265 function, "matrixCompMult", Math::multiply, variable_type /* res_type */, variable_type /* arg1_type */,
14266 variable_type /* arg2_type */);
14272 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14273 glw::GLdouble /* Arg2T */>(
14274 function, "max", Math::max, variable_type /* res_type */, variable_type /* arg1_type */,
14275 variable_type /* arg2_type */);
14279 case FUNCTION_MAX_AGAINST_SCALAR:
14281 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14282 glw::GLdouble /* Arg2T */>(
14283 function, "max", Math::max, variable_type /* res_type */, variable_type /* arg1_type */,
14284 scalar_type /* arg2_type */);
14290 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14291 glw::GLdouble /* Arg2T */>(
14292 function, "min", Math::min, variable_type /* res_type */, variable_type /* arg1_type */,
14293 variable_type /* arg2_type */);
14297 case FUNCTION_MIN_AGAINST_SCALAR:
14299 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14300 glw::GLdouble /* Arg2T */>(
14301 function, "min", Math::min, variable_type /* res_type */, variable_type /* arg1_type */,
14302 scalar_type /* arg2_type */);
14308 return new FunctionObject::tenaryByComponent(function, "mix", Math::mix, variable_type /* res_type */,
14309 variable_type /* arg1_type */, variable_type /* arg2_type */,
14310 variable_type /* arg3_type */);
14316 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14317 glw::GLdouble /* Arg2T */>(
14318 function, "mod", Math::mod, variable_type /* res_type */, variable_type /* arg1_type */,
14319 variable_type /* arg2_type */);
14323 case FUNCTION_MOD_AGAINST_SCALAR:
14325 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14326 glw::GLdouble /* Arg2T */>(
14327 function, "mod", Math::mod, variable_type /* res_type */, variable_type /* arg1_type */,
14328 scalar_type /* arg2_type */);
14332 case FUNCTION_MODF:
14334 return new FunctionObject::unaryWithOutputByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* ArgT */,
14335 glw::GLdouble /* OutT */>(
14336 function, "modf", Math::modf, variable_type /* res_type */, variable_type /* arg_type */,
14337 variable_type /* out_type */);
14341 case FUNCTION_NORMALIZE:
14343 switch (variable_type)
14345 case Utils::VARIABLE_TYPE_DVEC2:
14346 return new FunctionObject::unary<tcu::DVec2 /* ResT */, tcu::DVec2 /* ArgT */>(function, "normalize",
14349 case Utils::VARIABLE_TYPE_DVEC3:
14350 return new FunctionObject::unary<tcu::DVec3 /* ResT */, tcu::DVec3 /* ArgT */>(function, "normalize",
14353 case Utils::VARIABLE_TYPE_DVEC4:
14354 return new FunctionObject::unary<tcu::DVec4 /* ResT */, tcu::DVec4 /* ArgT */>(function, "normalize",
14363 case FUNCTION_NOTEQUAL:
14365 switch (variable_type)
14367 case Utils::VARIABLE_TYPE_DVEC2:
14368 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14369 function, "notEqual", Math::notEqual);
14371 case Utils::VARIABLE_TYPE_DVEC3:
14372 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14373 function, "notEqual", Math::notEqual);
14375 case Utils::VARIABLE_TYPE_DVEC4:
14376 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14377 function, "notEqual", Math::notEqual);
14385 case FUNCTION_OUTERPRODUCT:
14387 switch (variable_type)
14389 case Utils::VARIABLE_TYPE_DMAT2:
14390 return new FunctionObject::binary<DMat2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14391 function, "outerProduct", Math::outerProduct);
14393 case Utils::VARIABLE_TYPE_DMAT2X3:
14394 return new FunctionObject::binary<DMat2x3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14395 function, "outerProduct", Math::outerProduct);
14397 case Utils::VARIABLE_TYPE_DMAT2X4:
14398 return new FunctionObject::binary<DMat2x4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14399 function, "outerProduct", Math::outerProduct);
14401 case Utils::VARIABLE_TYPE_DMAT3:
14402 return new FunctionObject::binary<DMat3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14403 function, "outerProduct", Math::outerProduct);
14405 case Utils::VARIABLE_TYPE_DMAT3X2:
14406 return new FunctionObject::binary<DMat3x2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14407 function, "outerProduct", Math::outerProduct);
14409 case Utils::VARIABLE_TYPE_DMAT3X4:
14410 return new FunctionObject::binary<DMat3x4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14411 function, "outerProduct", Math::outerProduct);
14413 case Utils::VARIABLE_TYPE_DMAT4:
14414 return new FunctionObject::binary<DMat4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14415 function, "outerProduct", Math::outerProduct);
14417 case Utils::VARIABLE_TYPE_DMAT4X2:
14418 return new FunctionObject::binary<DMat4x2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14419 function, "outerProduct", Math::outerProduct);
14421 case Utils::VARIABLE_TYPE_DMAT4X3:
14422 return new FunctionObject::binary<DMat4x3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14423 function, "outerProduct", Math::outerProduct);
14431 case FUNCTION_PACKDOUBLE2X32:
14433 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::UVec2 /* ArgT */>(function, "packDouble2x32",
14434 Math::packDouble2x32);
14438 case FUNCTION_REFLECT:
14440 switch (variable_type)
14442 case Utils::VARIABLE_TYPE_DVEC2:
14443 return new FunctionObject::binary<tcu::DVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14444 function, "reflect", tcu::reflect);
14446 case Utils::VARIABLE_TYPE_DVEC3:
14447 return new FunctionObject::binary<tcu::DVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14448 function, "reflect", tcu::reflect);
14450 case Utils::VARIABLE_TYPE_DVEC4:
14451 return new FunctionObject::binary<tcu::DVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14452 function, "reflect", tcu::reflect);
14460 case FUNCTION_REFRACT:
14462 switch (variable_type)
14464 case Utils::VARIABLE_TYPE_DVEC2:
14465 return new FunctionObject::tenary<tcu::DVec2 /* ResT */, const tcu::DVec2& /* Arg1T */,
14466 const tcu::DVec2& /* Arg2T */, glw::GLdouble /* Arg3T */>(
14467 function, "refract", tcu::refract);
14469 case Utils::VARIABLE_TYPE_DVEC3:
14470 return new FunctionObject::tenary<tcu::DVec3 /* ResT */, const tcu::DVec3& /* Arg1T */,
14471 const tcu::DVec3& /* Arg2T */, glw::GLdouble /* Arg3T */>(
14472 function, "refract", tcu::refract);
14474 case Utils::VARIABLE_TYPE_DVEC4:
14475 return new FunctionObject::tenary<tcu::DVec4 /* ResT */, const tcu::DVec4& /* Arg1T */,
14476 const tcu::DVec4& /* Arg2T */, glw::GLdouble /* Arg3T */>(
14477 function, "refract", tcu::refract);
14485 case FUNCTION_ROUND:
14487 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14488 function, "round", Math::round, variable_type /* res_type */, variable_type /* arg_type */);
14492 case FUNCTION_ROUNDEVEN:
14494 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14495 function, "roundEven", Math::roundEven, variable_type /* res_type */, variable_type /* arg_type */);
14499 case FUNCTION_SIGN:
14501 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14502 function, "sign", Math::sign, variable_type /* res_type */, variable_type /* arg_type */);
14506 case FUNCTION_SMOOTHSTEP:
14508 return new FunctionObject::tenaryByComponent(function, "smoothstep", Math::smoothStep,
14509 variable_type /* res_type */, variable_type /* arg1_type */,
14510 variable_type /* arg2_type */, variable_type /* arg3_type */);
14514 case FUNCTION_SMOOTHSTEP_AGAINST_SCALAR:
14516 return new FunctionObject::tenaryByComponent(function, "smoothstep", Math::smoothStep,
14517 variable_type /* res_type */, scalar_type /* arg1_type */,
14518 scalar_type /* arg2_type */, variable_type /* arg3_type */);
14522 case FUNCTION_SQRT:
14524 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14525 function, "sqrt", sqrt, variable_type /* res_type */, variable_type /* arg_type */);
14529 case FUNCTION_STEP:
14531 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14532 glw::GLdouble /* Arg2T */>(
14533 function, "step", Math::step, variable_type /* res_type */, variable_type /* arg1_type */,
14534 variable_type /* arg2_type */);
14538 case FUNCTION_STEP_AGAINST_SCALAR:
14540 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14541 glw::GLdouble /* Arg2T */>(
14542 function, "step", Math::step, variable_type /* res_type */, scalar_type /* arg1_type */,
14543 variable_type /* arg2_type */);
14547 case FUNCTION_TRANSPOSE:
14549 switch (variable_type)
14551 case Utils::VARIABLE_TYPE_DMAT2:
14552 return new FunctionObject::unary<DMat2 /* ResT */, DMat2 /* ArgT */>(function, "transpose",
14555 case Utils::VARIABLE_TYPE_DMAT2X3:
14556 return new FunctionObject::unary<DMat2x3 /* ResT */, DMat3x2 /* ArgT */>(function, "transpose",
14559 case Utils::VARIABLE_TYPE_DMAT2X4:
14560 return new FunctionObject::unary<DMat2x4 /* ResT */, DMat4x2 /* ArgT */>(function, "transpose",
14563 case Utils::VARIABLE_TYPE_DMAT3:
14564 return new FunctionObject::unary<DMat3 /* ResT */, DMat3 /* ArgT */>(function, "transpose",
14567 case Utils::VARIABLE_TYPE_DMAT3X2:
14568 return new FunctionObject::unary<DMat3x2 /* ResT */, DMat2x3 /* ArgT */>(function, "transpose",
14571 case Utils::VARIABLE_TYPE_DMAT3X4:
14572 return new FunctionObject::unary<DMat3x4 /* ResT */, DMat4x3 /* ArgT */>(function, "transpose",
14575 case Utils::VARIABLE_TYPE_DMAT4:
14576 return new FunctionObject::unary<DMat4 /* ResT */, DMat4 /* ArgT */>(function, "transpose",
14579 case Utils::VARIABLE_TYPE_DMAT4X2:
14580 return new FunctionObject::unary<DMat4x2 /* ResT */, DMat2x4 /* ArgT */>(function, "transpose",
14583 case Utils::VARIABLE_TYPE_DMAT4X3:
14584 return new FunctionObject::unary<DMat4x3 /* ResT */, DMat3x4 /* ArgT */>(function, "transpose",
14593 case FUNCTION_TRUNC:
14595 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14596 function, "trunc", Math::trunc, variable_type /* res_type */, variable_type /* arg_type */);
14600 case FUNCTION_UNPACKDOUBLE2X32:
14602 return new FunctionObject::unary<tcu::UVec2 /* ResT */, glw::GLdouble /* ArgT */>(function, "unpackDouble2x32",
14603 Math::unpackDouble2x32);
14607 case FUNCTION_ISNAN:
14609 return new FunctionObject::unaryByComponent<glw::GLuint /* ResT */>(
14610 function, "isnan", Math::isnan_impl, uint_type /* res_type */, variable_type /* arg_type */);
14614 case FUNCTION_ISINF:
14616 return new FunctionObject::unaryByComponent<glw::GLuint /* ResT */>(
14617 function, "isinf", Math::isinf_impl, uint_type /* res_type */, variable_type /* arg_type */);
14622 TCU_FAIL("Not implemented");
14627 TCU_FAIL("Not implemented");
14631 /** Get gl.uniform* that match type of argument. Assumes that type is matrix of double.
14633 * @param argument Argument index
14634 * @param function_object Function object
14636 * @return Function pointer
14638 BuiltinFunctionTest::uniformDMatFunctionPointer BuiltinFunctionTest::getUniformFunctionForDMat(
14639 glw::GLuint argument, const functionObject& function_object) const
14641 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14642 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14644 switch (argument_type)
14646 case Utils::VARIABLE_TYPE_DMAT2:
14647 return gl.uniformMatrix2dv;
14649 case Utils::VARIABLE_TYPE_DMAT2X3:
14650 return gl.uniformMatrix2x3dv;
14652 case Utils::VARIABLE_TYPE_DMAT2X4:
14653 return gl.uniformMatrix2x4dv;
14655 case Utils::VARIABLE_TYPE_DMAT3:
14656 return gl.uniformMatrix3dv;
14658 case Utils::VARIABLE_TYPE_DMAT3X2:
14659 return gl.uniformMatrix3x2dv;
14661 case Utils::VARIABLE_TYPE_DMAT3X4:
14662 return gl.uniformMatrix3x4dv;
14664 case Utils::VARIABLE_TYPE_DMAT4:
14665 return gl.uniformMatrix4dv;
14667 case Utils::VARIABLE_TYPE_DMAT4X2:
14668 return gl.uniformMatrix4x2dv;
14670 case Utils::VARIABLE_TYPE_DMAT4X3:
14671 return gl.uniformMatrix4x3dv;
14677 TCU_FAIL("Not implemented");
14681 /** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of double.
14683 * @param argument Argument index
14684 * @param function_object Function object
14686 * @return Function pointer
14688 BuiltinFunctionTest::uniformDVecFunctionPointer BuiltinFunctionTest::getUniformFunctionForDVec(
14689 glw::GLuint argument, const functionObject& function_object) const
14691 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14692 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14694 switch (argument_type)
14696 case Utils::VARIABLE_TYPE_DOUBLE:
14697 return gl.uniform1dv;
14699 case Utils::VARIABLE_TYPE_DVEC2:
14700 return gl.uniform2dv;
14702 case Utils::VARIABLE_TYPE_DVEC3:
14703 return gl.uniform3dv;
14705 case Utils::VARIABLE_TYPE_DVEC4:
14706 return gl.uniform4dv;
14709 TCU_FAIL("Not implemented");
14716 /** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of signed integer.
14718 * @param argument Argument index
14719 * @param function_object Function object
14721 * @return Function pointer
14723 BuiltinFunctionTest::uniformIVecFunctionPointer BuiltinFunctionTest::getUniformFunctionForIVec(
14724 glw::GLuint argument, const functionObject& function_object) const
14726 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14727 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14729 switch (argument_type)
14731 case Utils::VARIABLE_TYPE_INT:
14732 return gl.uniform1iv;
14734 case Utils::VARIABLE_TYPE_IVEC2:
14735 return gl.uniform2iv;
14737 case Utils::VARIABLE_TYPE_IVEC3:
14738 return gl.uniform3iv;
14740 case Utils::VARIABLE_TYPE_IVEC4:
14741 return gl.uniform4iv;
14744 TCU_FAIL("Not implemented");
14751 /** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of unsigned integer.
14753 * @param argument Argument index
14754 * @param function_object Function object
14756 * @return Function pointer
14758 BuiltinFunctionTest::uniformUVecFunctionPointer BuiltinFunctionTest::getUniformFunctionForUVec(
14759 glw::GLuint argument, const functionObject& function_object) const
14761 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14762 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14764 switch (argument_type)
14766 case Utils::VARIABLE_TYPE_UVEC2:
14767 return gl.uniform2uiv;
14770 TCU_FAIL("Not implemented");
14777 /** Get name of uniform that will be used as <argument>.
14779 * @param argument Argument index
14781 * @return Name of uniform
14783 const glw::GLchar* BuiltinFunctionTest::getUniformName(glw::GLuint argument) const
14788 return "uniform_0";
14791 return "uniform_1";
14794 return "uniform_2";
14797 TCU_FAIL("Not implemented");
14803 /** Get name of varying that will be used as <result>.
14805 * @param result Result index
14807 * @return Name of varying
14809 const glw::GLchar* BuiltinFunctionTest::getVaryingName(glw::GLuint result) const
14823 TCU_FAIL("Not implemented");
14829 /** Check if given combination of function and type is implemented
14831 * @param function Function enumeration
14832 * @param type Type details
14834 * @return true if function is available for given type, false otherwise
14836 bool BuiltinFunctionTest::isFunctionImplemented(FunctionEnum function, const typeDetails& type) const
14838 static const bool look_up_table[][3] = {
14839 /* SCALAR, VECTOR, MATRIX */
14840 /* FUNCTION_ABS: */ { true, true, false },
14841 /* FUNCTION_CEIL: */ { true, true, false },
14842 /* FUNCTION_CLAMP: */ { true, true, false },
14843 /* FUNCTION_CLAMP_AGAINST_SCALAR: */ { false, true, false },
14844 /* FUNCTION_CROSS: */ { false, true, false },
14845 /* FUNCTION_DETERMINANT: */ { false, false, true },
14846 /* FUNCTION_DISTANCE: */ { false, true, false },
14847 /* FUNCTION_DOT: */ { false, true, false },
14848 /* FUNCTION_EQUAL: */ { false, true, false },
14849 /* FUNCTION_FACEFORWARD: */ { false, true, false },
14850 /* FUNCTION_FLOOR: */ { true, true, false },
14851 /* FUNCTION_FMA: */ { true, true, false },
14852 /* FUNCTION_FRACT: */ { true, true, false },
14853 /* FUNCTION_FREXP: */ { true, true, false },
14854 /* FUNCTION_GREATERTHAN: */ { false, true, false },
14855 /* FUNCTION_GREATERTHANEQUAL: */ { false, true, false },
14856 /* FUNCTION_INVERSE: */ { false, false, true },
14857 /* FUNCTION_INVERSESQRT: */ { true, true, false },
14858 /* FUNCTION_LDEXP: */ { true, true, false },
14859 /* FUNCTION_LESSTHAN: */ { false, true, false },
14860 /* FUNCTION_LESSTHANEQUAL: */ { false, true, false },
14861 /* FUNCTION_LENGTH: */ { false, true, false },
14862 /* FUNCTION_MATRIXCOMPMULT: */ { false, false, true },
14863 /* FUNCTION_MAX: */ { true, true, false },
14864 /* FUNCTION_MAX_AGAINST_SCALAR: */ { false, true, false },
14865 /* FUNCTION_MIN: */ { true, true, false },
14866 /* FUNCTION_MIN_AGAINST_SCALAR: */ { false, true, false },
14867 /* FUNCTION_MIX: */ { true, true, false },
14868 /* FUNCTION_MOD: */ { true, true, false },
14869 /* FUNCTION_MOD_AGAINST_SCALAR: */ { false, true, false },
14870 /* FUNCTION_MODF: */ { true, true, false },
14871 /* FUNCTION_NORMALIZE: */ { false, true, false },
14872 /* FUNCTION_NOTEQUAL: */ { false, true, false },
14873 /* FUNCTION_OUTERPRODUCT: */ { false, false, true },
14874 /* FUNCTION_PACKDOUBLE2X32: */ { true, false, false },
14875 /* FUNCTION_REFLECT: */ { false, true, false },
14876 /* FUNCTION_REFRACT: */ { false, true, false },
14877 /* FUNCTION_ROUND: */ { true, true, false },
14878 /* FUNCTION_ROUNDEVEN: */ { true, true, false },
14879 /* FUNCTION_SIGN: */ { true, false, false },
14880 /* FUNCTION_SMOOTHSTEP: */ { true, true, false },
14881 /* FUNCTION_SMOOTHSTEP_AGAINST_SCALAR: */ { false, true, false },
14882 /* FUNCTION_SQRT: */ { true, true, false },
14883 /* FUNCTION_STEP: */ { true, true, false },
14884 /* FUNCTION_STEP_AGAINST_SCALAR: */ { false, true, false },
14885 /* FUNCTION_TRANSPOSE: */ { false, false, false },
14886 /* FUNCTION_TRUNC: */ { true, true, false },
14887 /* FUNCTION_UNPACKDOUBLE2X32: */ { true, false, false },
14888 /* FUNCTION_ISNAN: */ { true, true, false },
14889 /* FUNCTION_ISINF: */ { true, true, false },
14892 bool result = look_up_table[function][type.m_general_type];
14894 if (true == result)
14898 case FUNCTION_CROSS: /* Only 3 element vectors */
14899 result = (3 == type.m_n_rows);
14901 case FUNCTION_DETERMINANT: /* Only square matrices */
14902 case FUNCTION_INVERSE:
14903 result = (type.m_n_columns == type.m_n_rows);
14913 /** Logs variable of given type: name (type) [values]
14915 * @param buffer Source of data
14916 * @param name Name of variable
14917 * @param type Type of variable
14919 void BuiltinFunctionTest::logVariableType(const glw::GLvoid* buffer, const glw::GLchar* name,
14920 Utils::_variable_type type) const
14922 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
14923 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
14924 tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
14926 message << name << " (" << Utils::getVariableTypeString(type) << ") [";
14928 for (glw::GLuint component = 0; component < n_components; ++component)
14930 if (0 != component)
14937 case Utils::VARIABLE_TYPE_DOUBLE:
14938 message << ((glw::GLdouble*)buffer)[component];
14940 case Utils::VARIABLE_TYPE_INT:
14941 message << ((glw::GLint*)buffer)[component];
14943 case Utils::VARIABLE_TYPE_UINT:
14944 message << ((glw::GLuint*)buffer)[component];
14947 TCU_FAIL("Not implemented");
14951 message << "]" << tcu::TestLog::EndMessage;
14954 /** Prepare input arguments, data are stored in <buffer>
14956 * @param function_object Function object
14957 * @param vertex Vertex index
14958 * @param buffer Buffer pointer
14960 void BuiltinFunctionTest::prepareArgument(const functionObject& function_object, glw::GLuint vertex,
14961 glw::GLubyte* buffer)
14963 const glw::GLuint n_arguments = function_object.getArgumentCount();
14965 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
14967 const glw::GLuint offset = function_object.getArgumentOffset(argument);
14969 prepareComponents(function_object, vertex, argument, buffer + offset);
14973 /** Prepare components for given <function_object>, <vertex> and <argument>
14975 * @param function_object Function object
14976 * @param vertex Vertex index
14977 * @param argument Argument index
14978 * @param buffer Buffer pointer
14980 void BuiltinFunctionTest::prepareComponents(const functionObject& function_object, glw::GLuint vertex,
14981 glw::GLuint argument, glw::GLubyte* buffer)
14983 glw::GLuint argument_index[3] = { 0 };
14984 glw::GLuint argument_reset[3] = { 0 };
14985 glw::GLuint argument_step[3] = { 0 };
14986 glw::GLdouble double_argument_start[3] = { 0.0 };
14987 const Utils::_variable_type base_arg_type = Utils::getBaseVariableType(function_object.getArgumentType(argument));
14988 glw::GLuint int_argument_start = -4;
14989 const glw::GLuint n_arguments = function_object.getArgumentCount();
14990 const glw::GLuint n_components = function_object.getArgumentComponents(argument);
14991 glw::GLuint uint_argument_start = 0;
14993 switch (n_arguments)
14996 argument_step[0] = 1;
14997 argument_reset[0] = 1024;
14998 double_argument_start[0] = -511.5;
15001 argument_step[0] = 32;
15002 argument_step[1] = 1;
15003 argument_reset[0] = 32;
15004 argument_reset[1] = 32;
15005 double_argument_start[0] = -15.5;
15006 double_argument_start[1] = -15.5;
15009 argument_step[0] = 64;
15010 argument_step[1] = 8;
15011 argument_step[2] = 1;
15012 argument_reset[0] = 16;
15013 argument_reset[1] = 8;
15014 argument_reset[2] = 8;
15015 double_argument_start[0] = -7.5;
15016 double_argument_start[1] = -3.5;
15017 double_argument_start[2] = -3.5;
15020 TCU_FAIL("Not implemented");
15025 switch (function_object.getFunctionEnum())
15027 case FUNCTION_CLAMP: /* arg_2 must be less than arg_3 */
15028 case FUNCTION_CLAMP_AGAINST_SCALAR:
15029 double_argument_start[2] = 4.5;
15031 case FUNCTION_INVERSESQRT: /* inversesqrt is undefined for argument <= 0 */
15032 double_argument_start[0] = 16.5;
15034 case FUNCTION_SMOOTHSTEP: /* arg_1 must be less than arg_2 */
15035 case FUNCTION_SMOOTHSTEP_AGAINST_SCALAR:
15036 argument_step[0] = 1;
15037 argument_step[1] = 8;
15038 argument_step[2] = 64;
15039 argument_reset[0] = 8;
15040 argument_reset[1] = 8;
15041 argument_reset[2] = 16;
15042 double_argument_start[0] = -3.5;
15043 double_argument_start[1] = 4.5;
15044 double_argument_start[2] = -7.5;
15050 for (glw::GLuint i = 0; i < n_arguments; ++i)
15052 argument_index[i] = (vertex / argument_step[i]) % argument_reset[i];
15055 switch (base_arg_type)
15057 case Utils::VARIABLE_TYPE_DOUBLE:
15059 glw::GLdouble* argument_dst = (glw::GLdouble*)buffer;
15061 double_argument_start[argument] += argument_index[argument];
15063 for (glw::GLuint component = 0; component < n_components; ++component)
15065 glw::GLdouble value = double_argument_start[argument] + ((glw::GLdouble)component) / 8.0;
15067 switch (function_object.getFunctionEnum())
15069 case FUNCTION_ROUND: /* Result for 0.5 depends on implementation */
15070 if (0.5 == Math::fract(value))
15079 argument_dst[component] = value;
15083 case Utils::VARIABLE_TYPE_INT:
15085 glw::GLint* argument_dst = (glw::GLint*)buffer;
15087 uint_argument_start += argument_index[argument];
15089 for (glw::GLuint component = 0; component < n_components; ++component)
15091 const glw::GLint value = int_argument_start + component;
15093 argument_dst[component] = value;
15097 case Utils::VARIABLE_TYPE_UINT:
15099 glw::GLuint* argument_dst = (glw::GLuint*)buffer;
15101 uint_argument_start += argument_index[argument];
15103 for (glw::GLuint component = 0; component < n_components; ++component)
15105 const glw::GLuint value = uint_argument_start + component;
15107 argument_dst[component] = value;
15112 TCU_FAIL("Not implemented");
15118 /** Prepare programInfo for given functionObject
15120 * @param function_object Function object
15121 * @param out_program_info Program info
15123 void BuiltinFunctionTest::prepareProgram(const functionObject& function_object, Utils::programInfo& out_program_info)
15125 const glw::GLuint n_varying_names = function_object.getResultCount();
15126 static const glw::GLchar* varying_names[3] = { getVaryingName(0), getVaryingName(1), getVaryingName(2) };
15128 prepareVertexShaderCode(function_object);
15130 out_program_info.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* tes */, m_vertex_shader_code.c_str(),
15131 varying_names, n_varying_names);
15134 /** Prepare input data and expected results for given function object
15136 * @param function_object Function object
15138 void BuiltinFunctionTest::prepareTestData(const functionObject& function_object)
15140 const glw::GLuint result_stride = function_object.getResultStride();
15141 const glw::GLuint result_buffer_size = result_stride * m_n_veritces;
15142 const glw::GLuint argument_stride = function_object.getArgumentStride();
15143 const glw::GLuint argument_buffer_size = m_n_veritces * argument_stride;
15145 m_argument_data.clear();
15146 m_expected_results_data.clear();
15148 m_argument_data.resize(argument_buffer_size);
15149 m_expected_results_data.resize(result_buffer_size);
15151 for (glw::GLuint vertex = 0; vertex < m_n_veritces; ++vertex)
15153 const glw::GLuint result_offset = vertex * result_stride;
15154 glw::GLdouble* result_dst = (glw::GLdouble*)&m_expected_results_data[result_offset];
15155 const glw::GLuint argument_offset = vertex * argument_stride;
15156 glw::GLubyte* argument_dst = &m_argument_data[argument_offset];
15158 prepareArgument(function_object, vertex, argument_dst);
15159 function_object.call(result_dst, argument_dst);
15163 /** Prepare source code of vertex shader for given function object. Result is stored in m_vertex_shader_code.
15165 * @param function_object Function object
15167 void BuiltinFunctionTest::prepareVertexShaderCode(const functionObject& function_object)
15169 static const glw::GLchar* shader_template_code = "#version 400 core\n"
15171 "precision highp float;\n"
15173 "ARGUMENT_DEFINITION"
15175 "RESULT_DEFINITION"
15179 " RESULT_NAME = RESULT_TYPE(FUNCTION_NAME(ARGUMENT));\n"
15183 static const glw::GLchar* argument_definition_token = "ARGUMENT_DEFINITION";
15184 static const glw::GLchar* argument_token = "ARGUMENT";
15185 static const glw::GLchar* function_name_token = "FUNCTION_NAME";
15186 static const glw::GLchar* result_definition_token = "RESULT_DEFINITION";
15187 static const glw::GLchar* result_name_token = "RESULT_NAME";
15188 static const glw::GLchar* result_type_token = "RESULT_TYPE";
15189 static const glw::GLchar* uniform_name_token = "UNIFORM_NAME";
15190 static const glw::GLchar* uniform_type_token = "UNIFORM_TYPE";
15192 static const glw::GLchar* argument_definition = "uniform UNIFORM_TYPE UNIFORM_NAME;\nARGUMENT_DEFINITION";
15193 static const glw::GLchar* argument_str = ", UNIFORM_NAMEARGUMENT";
15194 static const glw::GLchar* first_argument = "UNIFORM_NAMEARGUMENT";
15195 static const glw::GLchar* result_definition = "flat out RESULT_TYPE RESULT_NAME;\nRESULT_DEFINITION";
15197 const glw::GLuint argument_definition_length = (glw::GLuint)strlen(argument_definition);
15198 const glw::GLuint first_argument_length = (glw::GLuint)strlen(first_argument);
15199 const glw::GLuint n_arguments = function_object.getArgumentCount();
15200 const glw::GLuint n_results = function_object.getResultCount();
15201 const glw::GLuint result_definition_length = (glw::GLuint)strlen(result_definition);
15202 std::string result_type = Utils::getVariableTypeString(function_object.getResultType(0));
15204 size_t search_position = 0;
15205 std::string string = shader_template_code;
15207 /* Replace ARGUMENT_DEFINITION with definitions */
15208 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
15210 Utils::_variable_type argument_type = function_object.getArgumentType(argument);
15211 const glw::GLchar* uniform_name = getUniformName(argument);
15212 std::string uniform_type = Utils::getVariableTypeString(argument_type);
15214 Utils::replaceToken(argument_definition_token, search_position, argument_definition, string);
15216 search_position -= argument_definition_length;
15218 Utils::replaceToken(uniform_type_token, search_position, uniform_type.c_str(), string);
15219 Utils::replaceToken(uniform_name_token, search_position, uniform_name, string);
15222 /* Remove ARGUMENT_DEFINITION */
15223 Utils::replaceToken(argument_definition_token, search_position, "", string);
15225 /* Replace RESULT_DEFINITION with definitions */
15226 for (glw::GLuint result = 0; result < n_results; ++result)
15228 Utils::_variable_type variable_type = function_object.getResultType(result);
15229 const glw::GLchar* varying_name = getVaryingName(result);
15230 std::string varying_type = Utils::getVariableTypeString(variable_type);
15232 Utils::replaceToken(result_definition_token, search_position, result_definition, string);
15234 search_position -= result_definition_length;
15236 Utils::replaceToken(result_type_token, search_position, varying_type.c_str(), string);
15237 Utils::replaceToken(result_name_token, search_position, varying_name, string);
15240 /* Remove RESULT_DEFINITION */
15241 Utils::replaceToken(result_definition_token, search_position, "", string);
15243 /* Replace RESULT_NAME */
15244 Utils::replaceToken(result_name_token, search_position, getVaryingName(0), string);
15246 /* Replace RESULT_TYPE */
15247 Utils::replaceToken(result_type_token, search_position, result_type.c_str(), string);
15249 /* Replace FUNCTION_NAME */
15250 Utils::replaceToken(function_name_token, search_position, function_object.getName(), string);
15252 /* Replace ARGUMENT with list of arguments */
15253 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
15255 const glw::GLchar* uniform_name = getUniformName(argument);
15259 Utils::replaceToken(argument_token, search_position, first_argument, string);
15263 Utils::replaceToken(argument_token, search_position, argument_str, string);
15266 search_position -= first_argument_length;
15268 Utils::replaceToken(uniform_name_token, search_position, uniform_name, string);
15271 for (glw::GLuint result = 1; result < n_results; ++result)
15273 const glw::GLchar* varying_name = getVaryingName(result);
15275 Utils::replaceToken(argument_token, search_position, argument_str, string);
15277 search_position -= first_argument_length;
15279 Utils::replaceToken(uniform_name_token, search_position, varying_name, string);
15282 /* Remove ARGUMENT */
15283 Utils::replaceToken(argument_token, search_position, "", string);
15285 m_vertex_shader_code = string;
15288 /** Test single function with one type
15290 * param function Function enumeration
15291 * param type Type details
15293 * @return true if test pass (or function is not available for <type>), false otherwise
15295 bool BuiltinFunctionTest::test(FunctionEnum function, const typeDetails& type)
15297 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15299 /* Skip if function is not implemented for type */
15300 if (false == isFunctionImplemented(function, type))
15305 Utils::programInfo program(m_context);
15306 de::UniquePtr<functionObject> function_object(getFunctionObject(function, type));
15308 prepareProgram(*function_object, program);
15309 prepareTestData(*function_object);
15311 /* Set up program */
15312 gl.useProgram(program.m_program_object_id);
15313 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
15315 for (glw::GLuint vertex = 0; vertex < m_n_veritces; ++vertex)
15317 testBegin(*function_object, program.m_program_object_id, vertex);
15319 gl.beginTransformFeedback(GL_POINTS);
15320 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
15322 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
15323 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
15325 gl.endTransformFeedback();
15326 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
15328 if (false == verifyResults(*function_object, vertex))
15337 /** Update transform feedback buffer and uniforms
15339 * @param function_object Function object
15340 * @param program_id Program object id
15341 * @param vertex Vertex index
15343 void BuiltinFunctionTest::testBegin(const functionObject& function_object, glw::GLuint program_id, glw::GLuint vertex)
15345 const glw::GLuint arguments_stride = function_object.getArgumentStride();
15346 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15347 const glw::GLuint n_arguments = function_object.getArgumentCount();
15348 const glw::GLuint result_buffer_size = function_object.getResultStride();
15349 const glw::GLuint vertex_offset = arguments_stride * vertex;
15351 /* Update transform feedback buffer */
15352 std::vector<glw::GLubyte> transform_feedback_buffer_data;
15353 transform_feedback_buffer_data.resize(result_buffer_size);
15355 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
15356 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
15358 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, result_buffer_size, &transform_feedback_buffer_data[0],
15360 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
15362 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_transform_feedback_buffer_id, 0 /* offset */,
15363 result_buffer_size);
15364 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
15367 gl.bindVertexArray(m_vertex_array_object_id);
15368 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
15370 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
15372 const glw::GLuint argument_offset = function_object.getArgumentOffset(argument);
15373 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
15374 const glw::GLuint n_columns = Utils::getNumberOfColumnsForVariableType(argument_type);
15375 const glw::GLchar* uniform_name = getUniformName(argument);
15376 const glw::GLint uniform_location = gl.getUniformLocation(program_id, uniform_name);
15377 const glw::GLdouble* uniform_src = (glw::GLdouble*)&m_argument_data[vertex_offset + argument_offset];
15379 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
15381 if (-1 == uniform_location)
15383 TCU_FAIL("Inactive uniform");
15386 if (1 == n_columns)
15388 switch (Utils::getBaseVariableType(argument_type))
15390 case Utils::VARIABLE_TYPE_DOUBLE:
15392 uniformDVecFunctionPointer p_uniform_function = getUniformFunctionForDVec(argument, function_object);
15394 p_uniform_function(uniform_location, 1 /* count */, uniform_src);
15397 case Utils::VARIABLE_TYPE_UINT:
15399 uniformUVecFunctionPointer p_uniform_function = getUniformFunctionForUVec(argument, function_object);
15401 p_uniform_function(uniform_location, 1 /* count */, (glw::GLuint*)uniform_src);
15404 case Utils::VARIABLE_TYPE_INT:
15406 uniformIVecFunctionPointer p_uniform_function = getUniformFunctionForIVec(argument, function_object);
15408 p_uniform_function(uniform_location, 1 /* count */, (glw::GLint*)uniform_src);
15412 TCU_FAIL("Not implemented");
15418 uniformDMatFunctionPointer p_uniform_function = getUniformFunctionForDMat(argument, function_object);
15420 p_uniform_function(uniform_location, 1 /* count */, GL_FALSE /* transpose */, uniform_src);
15425 /** Init GL obejcts
15428 void BuiltinFunctionTest::testInit()
15430 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15432 gl.genBuffers(1, &m_transform_feedback_buffer_id);
15433 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
15435 gl.genVertexArrays(1, &m_vertex_array_object_id);
15436 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
15438 gl.enable(GL_RASTERIZER_DISCARD);
15441 /** Compare contents of transform feedback buffer with expected results
15443 * @param function_object Function object
15444 * @param vertex Vertex index
15446 * @return true if all results are as expected, false otherwise
15448 bool BuiltinFunctionTest::verifyResults(const functionObject& function_object, glw::GLuint vertex)
15450 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15451 bool test_result = true;
15452 const glw::GLuint n_results = function_object.getResultCount();
15453 const glw::GLuint results_stride = function_object.getResultStride();
15454 const glw::GLuint results_offset = vertex * results_stride;
15455 const glw::GLubyte* expected_results = &m_expected_results_data[results_offset];
15457 /* Get transform feedback data */
15458 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
15459 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
15461 glw::GLubyte* feedback_data = (glw::GLubyte*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
15462 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
15464 for (glw::GLuint result = 0; result < n_results; ++result)
15466 const Utils::_variable_type result_type = function_object.getResultType(result);
15467 const glw::GLuint result_offset = function_object.getResultOffset(result);
15469 const glw::GLvoid* expected_result_src = expected_results + result_offset;
15470 const glw::GLvoid* result_src = feedback_data + result_offset;
15472 if (false == compare(result_type, expected_result_src, result_src))
15474 test_result = false;
15479 /* Unmap transform feedback buffer */
15480 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
15481 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
15483 if (false == test_result)
15485 const glw::GLuint argument_stride = function_object.getArgumentStride();
15486 const glw::GLuint arguments_offset = vertex * argument_stride;
15488 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
15489 << tcu::TestLog::EndMessage;
15491 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function: " << function_object.getName()
15492 << tcu::TestLog::EndMessage;
15494 for (glw::GLuint result = 0; result < n_results; ++result)
15496 const Utils::_variable_type result_type = function_object.getResultType(result);
15497 const glw::GLuint result_offset = function_object.getResultOffset(result);
15499 const glw::GLvoid* expected_result_src = expected_results + result_offset;
15500 const glw::GLvoid* result_src = feedback_data + result_offset;
15502 logVariableType(result_src, "Result", result_type);
15503 logVariableType(expected_result_src, "Expected result", result_type);
15506 for (glw::GLuint argument = 0; argument < function_object.getArgumentCount(); ++argument)
15508 const glw::GLuint argument_offset = function_object.getArgumentOffset(argument);
15509 const glw::GLubyte* argument_src = &m_argument_data[arguments_offset + argument_offset];
15511 logVariableType(argument_src, "Argument", function_object.getArgumentType(argument));
15514 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader:\n"
15515 << m_vertex_shader_code << tcu::TestLog::EndMessage;
15518 return test_result;
15523 * @param context Rendering context.
15525 GPUShaderFP64Tests::GPUShaderFP64Tests(deqp::Context& context)
15526 : TestCaseGroup(context, "gpu_shader_fp64", "Verifies \"gpu_shader_fp64\" functionality")
15528 /* Left blank on purpose */
15531 /** Initializes a texture_storage_multisample test group.
15534 void GPUShaderFP64Tests::init(void)
15536 TestCaseGroup* fp64 = new TestCaseGroup(m_context, "fp64", "");
15537 fp64->addChild(new GPUShaderFP64Test1(m_context));
15538 fp64->addChild(new GPUShaderFP64Test2(m_context));
15539 fp64->addChild(new GPUShaderFP64Test3(m_context));
15540 fp64->addChild(new GPUShaderFP64Test4(m_context));
15541 fp64->addChild(new GPUShaderFP64Test5(m_context));
15542 fp64->addChild(new GPUShaderFP64Test6(m_context));
15543 fp64->addChild(new GPUShaderFP64Test7(m_context));
15544 fp64->addChild(new GPUShaderFP64Test8(m_context));
15545 fp64->addChild(new GPUShaderFP64Test9(m_context));
15548 TypeDefinition typeDefinition[] =
15550 { "double", 1, 1 },
15555 { "dmat2x3", 2, 3 },
15556 { "dmat2x4", 2, 4 },
15557 { "dmat3x2", 3, 2 },
15559 { "dmat3x4", 3, 4 },
15560 { "dmat4x2", 4, 2 },
15561 { "dmat4x3", 4, 3 },
15565 struct BuiltinFunctions
15568 FunctionEnum function;
15569 } builtinFunctions[] = {
15570 { "abs", FUNCTION_ABS },
15571 { "ceil", FUNCTION_CEIL },
15572 { "clamp", FUNCTION_CLAMP },
15573 { "clamp_against_scalar", FUNCTION_CLAMP_AGAINST_SCALAR },
15574 { "cross", FUNCTION_CROSS },
15575 { "determinant", FUNCTION_DETERMINANT },
15576 { "distance", FUNCTION_DISTANCE },
15577 { "dot", FUNCTION_DOT },
15578 { "equal", FUNCTION_EQUAL },
15579 { "faceforward", FUNCTION_FACEFORWARD },
15580 { "floor", FUNCTION_FLOOR },
15581 { "fma", FUNCTION_FMA },
15582 { "fract", FUNCTION_FRACT },
15583 { "frexp", FUNCTION_FREXP },
15584 { "greaterthan", FUNCTION_GREATERTHAN },
15585 { "greaterthanequal", FUNCTION_GREATERTHANEQUAL },
15586 { "inverse", FUNCTION_INVERSE },
15587 { "inversesqrt", FUNCTION_INVERSESQRT },
15588 { "ldexp", FUNCTION_LDEXP },
15589 { "lessthan", FUNCTION_LESSTHAN },
15590 { "lessthanequal", FUNCTION_LESSTHANEQUAL },
15591 { "length", FUNCTION_LENGTH },
15592 { "matrixcompmult", FUNCTION_MATRIXCOMPMULT },
15593 { "max", FUNCTION_MAX },
15594 { "max_against_scalar", FUNCTION_MAX_AGAINST_SCALAR },
15595 { "min", FUNCTION_MIN },
15596 { "min_against_scalar", FUNCTION_MIN_AGAINST_SCALAR },
15597 { "mix", FUNCTION_MIX },
15598 { "mod", FUNCTION_MOD },
15599 { "mod_against_scalar", FUNCTION_MOD_AGAINST_SCALAR },
15600 { "modf", FUNCTION_MODF },
15601 { "normalize", FUNCTION_NORMALIZE },
15602 { "notequal", FUNCTION_NOTEQUAL },
15603 { "outerproduct", FUNCTION_OUTERPRODUCT },
15604 { "packdouble2x32", FUNCTION_PACKDOUBLE2X32 },
15605 { "reflect", FUNCTION_REFLECT },
15606 { "refract", FUNCTION_REFRACT },
15607 { "round", FUNCTION_ROUND },
15608 { "roundeven", FUNCTION_ROUNDEVEN },
15609 { "sign", FUNCTION_SIGN },
15610 { "smoothstep", FUNCTION_SMOOTHSTEP },
15611 { "smoothstep_against_scalar", FUNCTION_SMOOTHSTEP_AGAINST_SCALAR },
15612 { "sqrt", FUNCTION_SQRT },
15613 { "step", FUNCTION_STEP },
15614 { "step_against_scalar", FUNCTION_STEP_AGAINST_SCALAR },
15615 { "transpose", FUNCTION_TRANSPOSE },
15616 { "trunc", FUNCTION_TRUNC },
15617 { "unpackdouble2x32", FUNCTION_UNPACKDOUBLE2X32 },
15618 { "isnan", FUNCTION_ISNAN },
15619 { "isinf", FUNCTION_ISINF }
15622 TestCaseGroup* builin = new TestCaseGroup(m_context, "builtin", "");
15623 for (int i = 0; i < DE_LENGTH_OF_ARRAY(builtinFunctions); ++i)
15625 const BuiltinFunctions& bf = builtinFunctions[i];
15626 for (int j = 0; j < DE_LENGTH_OF_ARRAY(typeDefinition); ++j)
15628 std::string caseName = bf.name + "_" + typeDefinition[j].name;
15629 builin->addChild(new BuiltinFunctionTest(m_context, caseName, bf.function, typeDefinition[j]));
15635 } /* glcts namespace */