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 function objects required by "GPUShaderFP64Test10"
12169 namespace FunctionObject
12171 /** Maps variable type with enumeration Utils::_variable_type
12175 template <typename T>
12179 static const Utils::_variable_type variable_type =
12180 TypeHelpers::typeInfo<typename TypeHelpers::referenceToType<T>::result>::variable_type;
12183 /** Place data from <in> into <buffer>
12185 * @param buffer Buffer
12186 * @param in Input data
12188 template <typename T>
12192 static void set(glw::GLvoid* buffer, const T& in)
12198 /** Place tcu::Matrix data from <in> into <buffer>
12200 * @param buffer Buffer
12201 * @param in Input data
12203 template <int Cols, int Rows>
12204 class pack<tcu::Matrix<glw::GLdouble, Rows, Cols> >
12207 static void set(glw::GLvoid* buffer, const tcu::Matrix<glw::GLdouble, Rows, Cols>& in)
12209 glw::GLdouble* data = (glw::GLdouble*)buffer;
12211 for (glw::GLint column = 0; column < Cols; ++column)
12213 for (glw::GLint row = 0; row < Rows; ++row)
12215 glw::GLint index = column * Rows + row;
12217 data[index] = in(row, column);
12223 /** Get data of <out> from <buffer>
12225 * @param buffer Buffer
12226 * @param out Output data
12228 template <typename T>
12232 static void get(const glw::GLvoid* buffer, T& out)
12238 /** Get tcu::Matrix data from <buffer>
12240 * @param buffer Buffer
12241 * @param out Output data
12243 template <int Cols, int Rows>
12244 class unpack<tcu::Matrix<glw::GLdouble, Rows, Cols> >
12247 static void get(const glw::GLvoid* buffer, tcu::Matrix<glw::GLdouble, Rows, Cols>& out)
12249 const glw::GLdouble* data = (glw::GLdouble*)buffer;
12251 for (glw::GLint column = 0; column < Cols; ++column)
12253 for (glw::GLint row = 0; row < Rows; ++row)
12255 glw::GLint index = column * Rows + row;
12257 out(row, column) = data[index];
12263 /** Base of unary function classes
12266 class unaryBase : public GPUShaderFP64Test10::functionObject
12269 unaryBase(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12270 glw::GLvoid* function_pointer, const Utils::_variable_type res_type, const Utils::_variable_type arg_type)
12271 : functionObject(function_enum, function_name, function_pointer, res_type), m_arg_type(arg_type)
12275 virtual glw::GLuint getArgumentCount() const
12280 virtual Utils::_variable_type getArgumentType(glw::GLuint /* argument */) const
12286 const Utils::_variable_type m_arg_type;
12289 /** Unary function class. It treats input argument as one variable.
12291 * @tparam ResT Type of result
12292 * @tparam ArgT Type of argument
12294 template <typename ResT, typename ArgT>
12295 class unary : public unaryBase
12298 typedef ResT (*functionPointer)(const ArgT&);
12300 unary(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12301 functionPointer function_pointer)
12302 : unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
12303 typeInfo<ArgT>::variable_type)
12307 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
12312 unpack<ArgT>::get(argument_src, arg);
12314 functionPointer p_function = (functionPointer)m_p_function;
12316 result = p_function(arg);
12318 pack<ResT>::set(result_dst, result);
12322 /** Unary function class. It treats input argument as separate components.
12324 * @tparam ResT Type of result
12326 template <typename ResT>
12327 class unaryByComponent : public unaryBase
12330 typedef ResT (*functionPointer)(glw::GLdouble);
12332 unaryByComponent(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12333 functionPointer function_pointer, const Utils::_variable_type res_type,
12334 const Utils::_variable_type arg_type)
12335 : unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_type)
12339 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
12341 glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(m_arg_type);
12342 ResT* p_result = (ResT*)result_dst;
12343 glw::GLdouble* p_arg = (glw::GLdouble*)argument_src;
12345 functionPointer p_function = (functionPointer)m_p_function;
12347 for (glw::GLuint component = 0; component < n_components; ++component)
12349 p_result[component] = p_function(p_arg[component]);
12354 /** Class of functions with one input and one output parameter. It treats arguments as separate components.
12356 * @tparam ResT Type of result
12357 * @tparam ArgT Type of argument
12358 * @tparam OutT Type of output parameter
12360 template <typename ResT, typename ArgT, typename OutT>
12361 class unaryWithOutputByComponent : public unaryBase
12364 typedef ResT (*functionPointer)(ArgT, OutT&);
12366 unaryWithOutputByComponent(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12367 functionPointer function_pointer, const Utils::_variable_type res_type,
12368 const Utils::_variable_type arg_type, const Utils::_variable_type out_type)
12369 : unaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_type)
12370 , m_out_type(out_type)
12374 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
12376 ResT* p_result = (ResT*)result_dst;
12377 OutT* p_out = (OutT*)((glw::GLubyte*)result_dst + getResultOffset(1));
12378 ArgT* p_arg = (ArgT*)argument_src;
12380 const glw::GLuint n_components_0 = getArgumentComponents(0);
12381 const glw::GLuint n_components_1 = getResultComponents(1);
12382 const glw::GLuint n_components = de::max(n_components_0, n_components_1);
12384 const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
12385 const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;
12387 functionPointer p_function = (functionPointer)m_p_function;
12389 for (glw::GLuint component = 0; component < n_components; ++component)
12391 const ArgT first_arg = p_arg[component * component_step_0];
12392 OutT& second_arg = p_out[component * component_step_1];
12394 p_result[component] = p_function(first_arg, second_arg);
12398 glw::GLuint getResultCount() const
12403 Utils::_variable_type getResultType(glw::GLuint result) const
12405 Utils::_variable_type type = Utils::VARIABLE_TYPE_UNKNOWN;
12416 TCU_FAIL("Not implemented");
12424 const Utils::_variable_type m_out_type;
12427 /** Base of binary function classes.
12430 class binaryBase : public GPUShaderFP64Test10::functionObject
12433 binaryBase(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12434 glw::GLvoid* function_pointer, const Utils::_variable_type res_type,
12435 const Utils::_variable_type arg_1_type, const Utils::_variable_type arg_2_type)
12436 : functionObject(function_enum, function_name, function_pointer, res_type)
12437 , m_arg_1_type(arg_1_type)
12438 , m_arg_2_type(arg_2_type)
12442 virtual glw::GLuint getArgumentCount() const
12447 virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const
12452 return m_arg_1_type;
12455 return m_arg_2_type;
12458 return Utils::VARIABLE_TYPE_UNKNOWN;
12464 const Utils::_variable_type m_arg_1_type;
12465 const Utils::_variable_type m_arg_2_type;
12468 /** Binary function class. It treats input arguments as two variables.
12470 * @param ResT Type of result
12471 * @param Arg1T Type of first argument
12472 * @param Arg2T Type of second argument
12474 template <typename ResT, typename Arg1T, typename Arg2T>
12475 class binary : public binaryBase
12478 typedef ResT (*functionPointer)(const Arg1T&, const Arg2T&);
12480 binary(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12481 functionPointer function_pointer)
12482 : binaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
12483 typeInfo<Arg1T>::variable_type, typeInfo<Arg2T>::variable_type)
12487 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
12489 const glw::GLuint argument_1_stride = getArgumentStride(0);
12491 functionPointer p_function = (functionPointer)m_p_function;
12497 unpack<Arg1T>::get(argument_src, arg_1);
12498 unpack<Arg2T>::get((glw::GLubyte*)argument_src + argument_1_stride, arg_2);
12500 result = p_function(arg_1, arg_2);
12502 pack<ResT>::set(result_dst, result);
12506 /** Binary function class. It treats input arguments as separate components.
12508 * @param ResT Type of result
12509 * @param Arg1T Type of first argument
12510 * @param Arg2T Type of second argument
12512 template <typename ResT, typename Arg1T, typename Arg2T>
12513 class binaryByComponent : public binaryBase
12516 typedef ResT (*functionPointer)(Arg1T, Arg2T);
12518 binaryByComponent(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12519 functionPointer function_pointer, const Utils::_variable_type res_type,
12520 const Utils::_variable_type arg_1_type, const Utils::_variable_type arg_2_type)
12521 : binaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_1_type, arg_2_type)
12525 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
12527 ResT* p_result = (ResT*)result_dst;
12528 Arg1T* p_arg_1 = (Arg1T*)argument_src;
12529 Arg2T* p_arg_2 = (Arg2T*)((glw::GLubyte*)argument_src + getArgumentOffset(1));
12531 const glw::GLuint n_components_0 = getArgumentComponents(0);
12532 const glw::GLuint n_components_1 = getArgumentComponents(1);
12533 const glw::GLuint n_components = de::max(n_components_0, n_components_1);
12535 const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
12536 const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;
12538 functionPointer p_function = (functionPointer)m_p_function;
12540 for (glw::GLuint component = 0; component < n_components; ++component)
12542 const Arg1T first_arg = p_arg_1[component * component_step_0];
12543 const Arg2T second_arg = p_arg_2[component * component_step_1];
12545 p_result[component] = p_function(first_arg, second_arg);
12550 /** Base of tenary function classes.
12553 class tenaryBase : public GPUShaderFP64Test10::functionObject
12556 tenaryBase(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12557 glw::GLvoid* function_pointer, const Utils::_variable_type res_type,
12558 const Utils::_variable_type arg_1_type, const Utils::_variable_type arg_2_type,
12559 const Utils::_variable_type arg_3_type)
12560 : functionObject(function_enum, function_name, function_pointer, res_type)
12561 , m_arg_1_type(arg_1_type)
12562 , m_arg_2_type(arg_2_type)
12563 , m_arg_3_type(arg_3_type)
12567 virtual glw::GLuint getArgumentCount() const
12572 virtual Utils::_variable_type getArgumentType(glw::GLuint argument) const
12577 return m_arg_1_type;
12580 return m_arg_2_type;
12583 return m_arg_3_type;
12586 return Utils::VARIABLE_TYPE_UNKNOWN;
12592 const Utils::_variable_type m_arg_1_type;
12593 const Utils::_variable_type m_arg_2_type;
12594 const Utils::_variable_type m_arg_3_type;
12597 /** Tenary function class. It treats input arguments as three variables.
12599 * @param ResT Type of result
12600 * @param Arg1T Type of first argument
12601 * @param Arg2T Type of second argument
12602 * @param Arg3T Type of third argument
12604 template <typename ResT, typename Arg1T, typename Arg2T, typename Arg3T>
12605 class tenary : public tenaryBase
12608 typedef ResT (*functionPointer)(Arg1T, Arg2T, Arg3T);
12609 typedef typename TypeHelpers::referenceToType<Arg1T>::result arg1T;
12610 typedef typename TypeHelpers::referenceToType<Arg2T>::result arg2T;
12611 typedef typename TypeHelpers::referenceToType<Arg3T>::result arg3T;
12613 tenary(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12614 functionPointer function_pointer)
12615 : tenaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, typeInfo<ResT>::variable_type,
12616 typeInfo<Arg1T>::variable_type, typeInfo<Arg2T>::variable_type, typeInfo<Arg3T>::variable_type)
12620 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
12622 const glw::GLuint argument_2_offset = getArgumentOffset(1);
12623 const glw::GLuint argument_3_offset = getArgumentOffset(2);
12625 functionPointer p_function = (functionPointer)m_p_function;
12632 unpack<arg1T>::get(argument_src, arg_1);
12633 unpack<arg2T>::get((glw::GLubyte*)argument_src + argument_2_offset, arg_2);
12634 unpack<arg3T>::get((glw::GLubyte*)argument_src + argument_3_offset, arg_3);
12636 result = p_function(arg_1, arg_2, arg_3);
12638 pack<ResT>::set(result_dst, result);
12642 /** Tenary function class. It treats input arguments as separate components.
12646 class tenaryByComponent : public tenaryBase
12649 typedef glw::GLdouble (*functionPointer)(glw::GLdouble, glw::GLdouble, glw::GLdouble);
12651 tenaryByComponent(GPUShaderFP64Test10::functionEnum function_enum, const glw::GLchar* function_name,
12652 functionPointer function_pointer, const Utils::_variable_type res_type,
12653 const Utils::_variable_type arg_1_type, const Utils::_variable_type arg_2_type,
12654 const Utils::_variable_type arg_3_type)
12655 : tenaryBase(function_enum, function_name, (glw::GLvoid*)function_pointer, res_type, arg_1_type, arg_2_type,
12660 virtual void call(glw::GLvoid* result_dst, const glw::GLvoid* argument_src) const
12662 glw::GLdouble* p_result = (glw::GLdouble*)result_dst;
12663 const glw::GLdouble* p_arg = (const glw::GLdouble*)argument_src;
12665 const glw::GLuint n_components_0 = getArgumentComponents(0);
12666 const glw::GLuint n_components_1 = getArgumentComponents(1);
12667 const glw::GLuint n_components_2 = getArgumentComponents(2);
12668 const glw::GLuint n_components = de::max(de::max(n_components_0, n_components_1), n_components_2);
12670 const glw::GLuint component_step_0 = (1 == n_components_0) ? 0 : 1;
12671 const glw::GLuint component_step_1 = (1 == n_components_1) ? 0 : 1;
12672 const glw::GLuint component_step_2 = (1 == n_components_2) ? 0 : 1;
12674 functionPointer p_function = (functionPointer)m_p_function;
12676 for (glw::GLuint component = 0; component < n_components; ++component)
12678 const glw::GLdouble first_arg = p_arg[component * component_step_0];
12679 const glw::GLdouble second_arg = p_arg[component * component_step_1 + n_components_0];
12680 const glw::GLdouble third_arg = p_arg[component * component_step_2 + n_components_0 + n_components_1];
12682 p_result[component] = p_function(first_arg, second_arg, third_arg);
12686 } /* FunctionObject */
12688 /** Implementations of "math" functions required by "GPUShaderFP64Test10"
12693 template <typename T>
12694 static T clamp(T x, T minVal, T maxVal);
12696 template <int Size>
12697 static tcu::Matrix<glw::GLdouble, Size, Size> cofactors(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix);
12699 template <int Size>
12700 static tcu::Vector<glw::GLuint, Size> convertBvecToUvec(const tcu::Vector<bool, Size>& src);
12702 template <typename T>
12703 static T determinant(T val);
12705 template <typename T>
12706 static T determinant(const tcu::Matrix<T, 2, 2>& mat);
12708 template <typename T>
12709 static T determinant(const tcu::Matrix<T, 3, 3>& mat);
12711 template <typename T>
12712 static T determinant(const tcu::Matrix<T, 4, 4>& mat);
12714 template <int Size>
12715 static tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminate(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix,
12716 glw::GLuint column, glw::GLuint row);
12718 template <int Size>
12719 static tcu::Vector<glw::GLuint, Size> equal(const tcu::Vector<glw::GLdouble, Size>& left,
12720 const tcu::Vector<glw::GLdouble, Size>& right);
12722 static glw::GLdouble fma(glw::GLdouble a, glw::GLdouble b, glw::GLdouble c);
12724 static glw::GLdouble fract(glw::GLdouble val);
12726 template <typename T>
12727 static T frexp(T val, glw::GLint& exp);
12729 template <int Size>
12730 static tcu::Vector<glw::GLuint, Size> greaterThan(const tcu::Vector<glw::GLdouble, Size>& left,
12731 const tcu::Vector<glw::GLdouble, Size>& right);
12733 template <int Size>
12734 static tcu::Vector<glw::GLuint, Size> greaterThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12735 const tcu::Vector<glw::GLdouble, Size>& right);
12737 template <int Size>
12738 static tcu::Matrix<glw::GLdouble, Size, Size> inverse(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix);
12740 static glw::GLdouble inverseSqrt(glw::GLdouble val);
12742 static glw::GLuint isinf_impl(glw::GLdouble val);
12744 static glw::GLuint isnan_impl(glw::GLdouble val);
12746 template <typename T>
12747 static T ldexp(T val, glw::GLint exp);
12749 template <int Size>
12750 static tcu::Vector<glw::GLuint, Size> lessThan(const tcu::Vector<glw::GLdouble, Size>& left,
12751 const tcu::Vector<glw::GLdouble, Size>& right);
12753 template <int Size>
12754 static tcu::Vector<glw::GLuint, Size> lessThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12755 const tcu::Vector<glw::GLdouble, Size>& right);
12757 template <typename T>
12758 static T max(T left, T right);
12760 template <typename T>
12761 static T min(T left, T right);
12763 template <int Size>
12764 static glw::GLdouble minor_impl(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix, glw::GLuint column,
12767 template <typename T>
12768 static T mix(T left, T right, T weight);
12770 template <typename T>
12771 static T mod(T left, T right);
12773 template <typename T>
12774 static T modf(T val, T& integer);
12776 template <typename T>
12777 static T multiply(T left, T right);
12779 template <int Size>
12780 static tcu::Vector<glw::GLuint, Size> notEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12781 const tcu::Vector<glw::GLdouble, Size>& right);
12783 template <int Cols, int Rows>
12784 static tcu::Matrix<glw::GLdouble, Rows, Cols> outerProduct(const tcu::Vector<glw::GLdouble, Rows>& left,
12785 const tcu::Vector<glw::GLdouble, Cols>& right);
12787 static glw::GLdouble packDouble2x32(const tcu::UVec2& in);
12789 template <typename T>
12790 static T round(T t);
12792 template <typename T>
12793 static T roundEven(T t);
12795 template <typename T>
12796 static T sign(T t);
12798 template <typename T>
12799 static T smoothStep(T e0, T e1, T val);
12801 template <typename T>
12802 static T step(T edge, T val);
12804 template <typename T, int Rows, int Cols>
12805 static tcu::Matrix<T, Cols, Rows> transpose(const tcu::Matrix<T, Rows, Cols>& matrix);
12807 template <typename T>
12808 static T trunc(T t);
12810 static tcu::UVec2 unpackDouble2x32(const glw::GLdouble& val);
12812 template <typename T>
12813 static T clamp(T x, T minVal, T maxVal)
12815 return min(max(x, minVal), maxVal);
12818 template <int Size>
12819 static tcu::Matrix<glw::GLdouble, Size, Size> cofactors(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix)
12821 tcu::Matrix<glw::GLdouble, Size, Size> result;
12823 for (glw::GLuint c = 0; c < Size; ++c)
12825 for (glw::GLuint r = 0; r < Size; ++r)
12827 const glw::GLdouble minor_value = minor_impl(matrix, c, r);
12829 result(r, c) = (1 == (c + r) % 2) ? -minor_value : minor_value;
12836 template <int Size>
12837 static tcu::Vector<glw::GLuint, Size> convertBvecToUvec(const tcu::Vector<bool, Size>& src)
12839 tcu::Vector<glw::GLuint, Size> result;
12841 for (glw::GLint i = 0; i < Size; ++i)
12843 if (GL_FALSE != src[i])
12856 template <typename T>
12857 static T det2(T _00, T _10, T _01, T _11)
12859 return _00 * _11 - _01 * _10;
12862 template <typename T>
12863 static T det3(T _00, T _10, T _20, T _01, T _11, T _21, T _02, T _12, T _22)
12865 return _00 * det2(_11, _21, _12, _22) - _10 * det2(_01, _21, _02, _22) + _20 * det2(_01, _11, _02, _12);
12868 template <typename T>
12869 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,
12872 return _00 * det3(_11, _21, _31, _12, _22, _32, _13, _23, _33) -
12873 _10 * det3(_01, _21, _31, _02, _22, _32, _03, _23, _33) +
12874 _20 * det3(_01, _11, _31, _02, _12, _32, _03, _13, _33) -
12875 _30 * det3(_01, _11, _21, _02, _12, _22, _03, _13, _23);
12878 template <typename T>
12879 static T determinant(T val)
12884 template <typename T>
12885 static T determinant(const tcu::Matrix<T, 2, 2>& mat)
12887 return det2(mat(0, 0), mat(0, 1), mat(1, 0), mat(1, 1));
12890 template <typename T>
12891 static T determinant(const tcu::Matrix<T, 3, 3>& mat)
12893 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));
12896 template <typename T>
12897 static T determinant(const tcu::Matrix<T, 4, 4>& mat)
12899 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),
12900 mat(2, 1), mat(2, 2), mat(2, 3), mat(3, 0), mat(3, 1), mat(3, 2), mat(3, 3));
12903 template <int Size>
12904 static tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminate(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix,
12905 glw::GLuint column, glw::GLuint row)
12907 tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> result;
12909 for (glw::GLuint c = 0; c < Size; ++c)
12911 /* Skip eliminated column */
12917 for (glw::GLuint r = 0; r < Size; ++r)
12919 /* Skip eliminated row */
12925 const glw::GLint r_offset = (r > row) ? -1 : 0;
12926 const glw::GLint c_offset = (c > column) ? -1 : 0;
12928 result(r + r_offset, c + c_offset) = matrix(r, c);
12935 template <int Size>
12936 static tcu::Vector<glw::GLuint, Size> equal(const tcu::Vector<glw::GLdouble, Size>& left,
12937 const tcu::Vector<glw::GLdouble, Size>& right)
12939 return convertBvecToUvec(tcu::equal(left, right));
12942 static glw::GLdouble fma(glw::GLdouble a, glw::GLdouble b, glw::GLdouble c)
12947 static glw::GLdouble fract(glw::GLdouble val)
12949 return val - floor(val);
12952 template <typename T>
12953 static T frexp(T val, glw::GLint& exp)
12955 return ::frexp(val, &exp);
12958 template <int Size>
12959 static tcu::Vector<glw::GLuint, Size> greaterThan(const tcu::Vector<glw::GLdouble, Size>& left,
12960 const tcu::Vector<glw::GLdouble, Size>& right)
12962 return convertBvecToUvec(tcu::greaterThan(left, right));
12965 template <int Size>
12966 static tcu::Vector<glw::GLuint, Size> greaterThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
12967 const tcu::Vector<glw::GLdouble, Size>& right)
12969 return convertBvecToUvec(tcu::greaterThanEqual(left, right));
12972 template <int Size>
12973 static tcu::Matrix<glw::GLdouble, Size, Size> inverse(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix)
12975 const tcu::Matrix<glw::GLdouble, Size, Size> cof = cofactors(matrix);
12976 const tcu::Matrix<glw::GLdouble, Size, Size> adjugate = tcu::transpose(cof);
12977 const glw::GLdouble det = determinant(matrix);
12978 const glw::GLdouble inv_det = 1.0 / det;
12980 tcu::Matrix<glw::GLdouble, Size, Size> result = adjugate * inv_det;
12985 static glw::GLdouble inverseSqrt(glw::GLdouble val)
12987 const glw::GLdouble root = sqrt(val);
12989 return (1.0 / root);
12992 static glw::GLuint isinf_impl(glw::GLdouble val)
12994 const glw::GLdouble infinity = std::numeric_limits<glw::GLdouble>::infinity();
12996 return ((infinity == val) || (-infinity == val));
12999 static glw::GLuint isnan_impl(glw::GLdouble val)
13004 template <typename T>
13005 static T ldexp(T val, glw::GLint exp)
13007 return ::ldexp(val, exp);
13010 template <int Size>
13011 static tcu::Vector<glw::GLuint, Size> lessThan(const tcu::Vector<glw::GLdouble, Size>& left,
13012 const tcu::Vector<glw::GLdouble, Size>& right)
13014 return convertBvecToUvec(tcu::lessThan(left, right));
13017 template <int Size>
13018 static tcu::Vector<glw::GLuint, Size> lessThanEqual(const tcu::Vector<glw::GLdouble, Size>& left,
13019 const tcu::Vector<glw::GLdouble, Size>& right)
13021 return convertBvecToUvec(tcu::lessThanEqual(left, right));
13024 template <typename T>
13025 static T max(T left, T right)
13027 return (left >= right) ? left : right;
13030 template <typename T>
13031 static T min(T left, T right)
13033 return (left <= right) ? left : right;
13036 template <int Size>
13037 static glw::GLdouble minor_impl(const tcu::Matrix<glw::GLdouble, Size, Size>& matrix, glw::GLuint column,
13040 tcu::Matrix<glw::GLdouble, Size - 1, Size - 1> eliminated = eliminate(matrix, column, row);
13042 return determinant(eliminated);
13046 glw::GLdouble minor_impl<2>(const tcu::Matrix<glw::GLdouble, 2, 2>& matrix, glw::GLuint column, glw::GLuint row)
13048 const glw::GLuint r = (0 == row) ? 1 : 0;
13049 const glw::GLuint c = (0 == column) ? 1 : 0;
13051 return matrix(r, c);
13054 template <typename T>
13055 static T mix(T left, T right, T weight)
13057 return left * (1 - weight) + right * (weight);
13060 template <typename T>
13061 static T mod(T left, T right)
13063 const T div_res = left / right;
13064 const T floored = floor(div_res);
13066 return left - right * floored;
13069 template <typename T>
13070 static T modf(T val, T& integer)
13072 return ::modf(val, &integer);
13075 template <typename T>
13076 static T multiply(T left, T right)
13078 T result = left * right;
13083 template <int Size>
13084 static tcu::Vector<glw::GLuint, Size> notEqual(const tcu::Vector<glw::GLdouble, Size>& left,
13085 const tcu::Vector<glw::GLdouble, Size>& right)
13087 return convertBvecToUvec(tcu::notEqual(left, right));
13090 template <int Cols, int Rows>
13091 static tcu::Matrix<glw::GLdouble, Rows, Cols> outerProduct(const tcu::Vector<glw::GLdouble, Rows>& left,
13092 const tcu::Vector<glw::GLdouble, Cols>& right)
13094 tcu::Matrix<glw::GLdouble, Rows, 1> left_mat;
13095 tcu::Matrix<glw::GLdouble, 1, Cols> right_mat;
13096 tcu::Matrix<glw::GLdouble, Rows, Cols> result;
13098 for (glw::GLuint i = 0; i < Rows; ++i)
13100 left_mat(i, 0) = left[i];
13103 for (glw::GLuint i = 0; i < Cols; ++i)
13105 right_mat(0, i) = right[i];
13108 result = left_mat * right_mat;
13113 static glw::GLdouble packDouble2x32(const tcu::UVec2& in)
13115 const glw::GLuint buffer[2] = { in[0], in[1] };
13116 glw::GLdouble result;
13117 memcpy(&result, buffer, sizeof(result));
13121 template <typename T>
13122 static T round(T t)
13127 if (((T)0.5) < frac)
13135 template <typename T>
13136 static T roundEven(T t)
13141 if (((T)0.5) < frac)
13145 else if ((((T)0.5) == frac) && (0 != ((int)res) % 2))
13153 template <typename T>
13170 template <typename T>
13171 static T smoothStep(T e0, T e1, T val)
13183 T temp = (val - e0) / (e1 - e0);
13185 T result = temp * temp * (3 - 2 * temp);
13190 template <typename T>
13191 static T step(T edge, T val)
13203 template <typename T, int Rows, int Cols>
13204 static tcu::Matrix<T, Cols, Rows> transpose(const tcu::Matrix<T, Rows, Cols>& matrix)
13206 tcu::Matrix<T, Cols, Rows> result = tcu::transpose(matrix);
13211 template <typename T>
13212 static T trunc(T t)
13214 const T abs_value = de::abs(t);
13215 const T result_value = floor(abs_value);
13217 const T result = sign(t) * result_value;
13222 static tcu::UVec2 unpackDouble2x32(const glw::GLdouble& val)
13224 glw::GLuint* ptr = (glw::GLuint*)&val;
13225 tcu::UVec2 result(ptr[0], ptr[1]);
13231 /* Constants used by GPUShaderFP64Test10 */
13232 /** Khronos Bug #14010
13233 * Using an epsilon value for comparing floating points is error prone.
13234 * Rather than writing a new floating point comparison function, I am
13235 * increasing the epsilon value to allow greater orders of magnitude
13236 * of floating point values.
13238 const glw::GLdouble GPUShaderFP64Test10::m_epsilon = 0.00002;
13239 const glw::GLuint GPUShaderFP64Test10::m_n_veritces = 1024;
13243 * @param context Rendering context.
13245 GPUShaderFP64Test10::GPUShaderFP64Test10(deqp::Context& context)
13246 : TestCase(context, "built_in_functions", "Verify that built-in functions support double-precision types")
13247 , m_transform_feedback_buffer_id(0)
13248 , m_vertex_array_object_id(0)
13250 /* Nothing to be done here */
13253 /** Deinitializes all GL objects that may have been created during test execution.
13256 void GPUShaderFP64Test10::deinit()
13258 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13260 /* Clean buffers */
13261 if (0 != m_transform_feedback_buffer_id)
13263 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
13264 gl.deleteBuffers(1, &m_transform_feedback_buffer_id);
13265 m_transform_feedback_buffer_id = 0;
13269 if (0 != m_vertex_array_object_id)
13271 gl.bindVertexArray(0);
13272 gl.deleteVertexArrays(1, &m_vertex_array_object_id);
13273 m_vertex_array_object_id = 0;
13279 * @return tcu::TestNode::STOP
13281 tcu::TestNode::IterateResult GPUShaderFP64Test10::iterate()
13283 bool result = true;
13285 /* Check if extension is supported */
13286 if (false == m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
13288 throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported");
13293 /* For each combination of function and type */
13294 for (std::vector<typeDetails>::const_iterator type = m_types.begin(); m_types.end() != type; ++type)
13296 for (std::vector<functionEnum>::const_iterator function = m_functions.begin(); m_functions.end() != function;
13299 if (false == test(*function, *type))
13307 if (true == result)
13309 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
13313 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
13317 return tcu::TestNode::STOP;
13322 * @param function_enum Function enumeration
13323 * @param function_name Function name
13324 * @param function_pointer Pointer to routine that wiil be executed
13325 * @param result_type Type of result
13327 GPUShaderFP64Test10::functionObject::functionObject(functionEnum function_enum, const glw::GLchar* function_name,
13328 glw::GLvoid* function_pointer, Utils::_variable_type result_type)
13329 : m_function_enum(function_enum)
13330 , m_function_name(function_name)
13331 , m_p_function(function_pointer)
13332 , m_res_type(result_type)
13334 /* Nothing to be done here */
13337 /** Get number of components for <argument>
13339 * @param argument Argument ordinal, starts with 0
13341 * @return Number of components
13343 glw::GLuint GPUShaderFP64Test10::functionObject::getArgumentComponents(glw::GLuint argument) const
13345 const Utils::_variable_type type = getArgumentType(argument);
13346 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13348 return n_components;
13351 /** Get size in bytes of single component of <argument>
13353 * @param argument Argument ordinal, starts with 0
13355 * @return Size of component
13357 glw::GLuint GPUShaderFP64Test10::functionObject::getArgumentComponentSize(glw::GLuint argument) const
13359 const Utils::_variable_type type = getArgumentType(argument);
13360 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
13361 const glw::GLuint base_type_size = Utils::getBaseVariableTypeComponentSize(base_type);
13363 return base_type_size;
13366 /** Get offset in bytes of <argument>. 0 is offset of first argument. Assumes tight packing.
13368 * @param argument Argument ordinal, starts with 0
13370 * @return Offset of arguemnt's data
13372 glw::GLuint GPUShaderFP64Test10::functionObject::getArgumentOffset(glw::GLuint argument) const
13374 glw::GLuint result = 0;
13376 for (glw::GLuint i = 0; i < argument; ++i)
13378 result += getArgumentStride(i);
13384 /** Get stride in bytes of all arguments
13386 * @return Stride of all arguments
13388 glw::GLuint GPUShaderFP64Test10::functionObject::getArgumentStride() const
13390 const glw::GLuint n_args = getArgumentCount();
13391 glw::GLuint result = 0;
13393 for (glw::GLuint i = 0; i < n_args; ++i)
13395 result += getArgumentStride(i);
13401 /** Get stride in bytes of <argument>
13403 * @param argument Argument ordinal, starts with 0
13405 * @return Stride of argument
13407 glw::GLuint GPUShaderFP64Test10::functionObject::getArgumentStride(glw::GLuint argument) const
13409 const glw::GLuint component_size = getArgumentComponentSize(argument);
13410 const glw::GLuint n_components = getArgumentComponents(argument);
13412 return n_components * component_size;
13415 /** Get function enumeration
13417 * @return Function enumeration
13419 GPUShaderFP64Test10::functionEnum GPUShaderFP64Test10::functionObject::getFunctionEnum() const
13421 return m_function_enum;
13424 /** Get function name
13426 * @return Function name
13428 const glw::GLchar* GPUShaderFP64Test10::functionObject::getName() const
13430 return m_function_name;
13433 /** Get number of components for <result>
13435 * @param result Result ordinal, starts with 0
13437 * @return Number of components
13439 glw::GLuint GPUShaderFP64Test10::functionObject::getResultComponents(glw::GLuint result) const
13441 const Utils::_variable_type type = getResultType(result);
13442 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13444 return n_components;
13447 /** Get number of results
13449 * @return Number of results
13451 glw::GLuint GPUShaderFP64Test10::functionObject::getResultCount() const
13456 /** Get offset in bytes of <result>. First result offset is 0. Assume tight packing.
13458 * @param result Result ordinal, starts with 0
13462 glw::GLuint GPUShaderFP64Test10::functionObject::getResultOffset(glw::GLuint result) const
13464 glw::GLuint offset = 0;
13466 for (glw::GLuint i = 0; i < result; ++i)
13468 offset += getResultStride(i);
13469 offset = deAlign32(offset, getBaseTypeSize(i));
13475 /** Get stride in bytes of <result>.
13477 * @param result Result ordinal, starts with 0
13481 glw::GLuint GPUShaderFP64Test10::functionObject::getResultStride(glw::GLuint result) const
13483 const Utils::_variable_type type = getResultType(result);
13484 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13486 return n_components * getBaseTypeSize(result);
13489 /** Get size in bytes of <result> base component.
13491 * @param result Result ordinal, starts with 0
13493 * @return Alignment
13495 glw::GLuint GPUShaderFP64Test10::functionObject::getBaseTypeSize(glw::GLuint result) const
13497 const Utils::_variable_type type = getResultType(result);
13498 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
13499 const glw::GLuint base_type_size = Utils::getBaseVariableTypeComponentSize(base_type);
13501 return base_type_size;
13504 /** Get stride in bytes of all results.
13508 glw::GLuint GPUShaderFP64Test10::functionObject::getResultStride() const
13510 const glw::GLuint n_results = getResultCount();
13511 glw::GLuint stride = 0;
13512 glw::GLuint maxAlignment = 0;
13514 for (glw::GLuint i = 0; i < n_results; ++i)
13516 const glw::GLuint alignment = getBaseTypeSize(i);
13517 stride += getResultStride(i);
13518 stride = deAlign32(stride, alignment);
13519 maxAlignment = deMaxu32(maxAlignment, alignment);
13522 // The stride of all results must also be aligned,
13523 // so results for next vertex are aligned.
13524 return deAlign32(stride, maxAlignment);
13527 /** Get type of <result>.
13529 * @param result Result ordinal, starts with 0
13533 Utils::_variable_type GPUShaderFP64Test10::functionObject::getResultType(glw::GLuint /* result */) const
13540 * @param n_columns Number of columns
13541 * @param n_rows Number of rows
13543 GPUShaderFP64Test10::typeDetails::typeDetails(glw::GLuint n_columns, glw::GLuint n_rows)
13544 : m_n_columns(n_columns), m_n_rows(n_rows)
13546 Utils::_variable_type type = Utils::getDoubleVariableType(n_columns, n_rows);
13547 m_type = Utils::getGLDataTypeOfVariableType(type);
13548 m_type_name = Utils::getVariableTypeString(type);
13550 if (1 == m_n_columns)
13554 m_general_type = SCALAR;
13558 m_general_type = VECTOR;
13563 m_general_type = MATRIX;
13567 /** Compare two values
13569 * @param type Type of values
13570 * @param left Pointer to left value
13571 * @param right Pointer to right value
13573 * @return true if values are equal, false otherwise
13575 bool GPUShaderFP64Test10::compare(Utils::_variable_type type, const glw::GLvoid* left, const glw::GLvoid* right)
13577 bool result = true;
13579 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
13580 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
13584 case Utils::VARIABLE_TYPE_DOUBLE:
13587 const glw::GLdouble* left_values = (glw::GLdouble*)left;
13588 const glw::GLdouble* right_values = (glw::GLdouble*)right;
13590 for (glw::GLuint component = 0; component < n_components; ++component)
13592 const glw::GLdouble left_value = left_values[component];
13593 const glw::GLdouble right_value = right_values[component];
13595 if ((left_value != right_value) && (m_epsilon < de::abs(left_value - right_value)) &&
13596 (0 == Math::isnan_impl(left_value)) && (0 == Math::isnan_impl(right_value)))
13606 case Utils::VARIABLE_TYPE_INT:
13609 const glw::GLint* left_values = (glw::GLint*)left;
13610 const glw::GLint* right_values = (glw::GLint*)right;
13612 for (glw::GLuint component = 0; component < n_components; ++component)
13614 const glw::GLint left_value = left_values[component];
13615 const glw::GLint right_value = right_values[component];
13617 if (left_value != right_value)
13627 case Utils::VARIABLE_TYPE_UINT:
13630 const glw::GLuint* left_values = (glw::GLuint*)left;
13631 const glw::GLuint* right_values = (glw::GLuint*)right;
13633 for (glw::GLuint component = 0; component < n_components; ++component)
13635 const glw::GLuint left_value = left_values[component];
13636 const glw::GLuint right_value = right_values[component];
13638 if (left_value != right_value)
13650 TCU_FAIL("Not implemented");
13658 /** Create instance of function object for given function enumeration and type
13660 * @param function Function enumeration
13661 * @param type Type details
13663 * @return Create object
13665 GPUShaderFP64Test10::functionObject* GPUShaderFP64Test10::getFunctionObject(functionEnum function,
13666 const typeDetails& type)
13668 typedef tcu::Matrix<glw::GLdouble, 2, 2> DMat2;
13669 typedef tcu::Matrix<glw::GLdouble, 3, 2> DMat2x3;
13670 typedef tcu::Matrix<glw::GLdouble, 4, 2> DMat2x4;
13671 typedef tcu::Matrix<glw::GLdouble, 2, 3> DMat3x2;
13672 typedef tcu::Matrix<glw::GLdouble, 3, 3> DMat3;
13673 typedef tcu::Matrix<glw::GLdouble, 4, 3> DMat3x4;
13674 typedef tcu::Matrix<glw::GLdouble, 2, 4> DMat4x2;
13675 typedef tcu::Matrix<glw::GLdouble, 3, 4> DMat4x3;
13676 typedef tcu::Matrix<glw::GLdouble, 4, 4> DMat4;
13678 const glw::GLuint n_columns = type.m_n_columns;
13679 const glw::GLuint n_rows = type.m_n_rows;
13680 const Utils::_variable_type scalar_type = Utils::getDoubleVariableType(1, 1);
13681 const Utils::_variable_type variable_type = Utils::getDoubleVariableType(n_columns, n_rows);
13682 const Utils::_variable_type uint_type = Utils::getUintVariableType(1, n_rows);
13683 const Utils::_variable_type int_type = Utils::getIntVariableType(1, n_rows);
13689 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
13690 function, "abs", de::abs, variable_type /* res_type */, variable_type /* arg_type */);
13694 case FUNCTION_CEIL:
13696 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
13697 function, "ceil", ceil, variable_type /* res_type */, variable_type /* arg_type */);
13701 case FUNCTION_CLAMP:
13703 return new FunctionObject::tenaryByComponent(function, "clamp", Math::clamp, variable_type /* res_type */,
13704 variable_type /* arg1_type */, variable_type /* arg2_type */,
13705 variable_type /* arg3_type */);
13708 case FUNCTION_CLAMP_AGAINST_SCALAR:
13710 return new FunctionObject::tenaryByComponent(function, "clamp", Math::clamp, variable_type /* res_type */,
13711 variable_type /* arg1_type */, scalar_type /* arg2_type */,
13712 scalar_type /* arg3_type */);
13715 case FUNCTION_CROSS:
13717 return new FunctionObject::binary<tcu::DVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13718 function, "cross", tcu::cross);
13722 case FUNCTION_DETERMINANT:
13724 switch (variable_type)
13726 case Utils::VARIABLE_TYPE_DMAT2:
13727 return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat2 /* ArgT */>(function, "determinant",
13728 Math::determinant);
13729 case Utils::VARIABLE_TYPE_DMAT3:
13730 return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat3 /* ArgT */>(function, "determinant",
13731 Math::determinant);
13732 case Utils::VARIABLE_TYPE_DMAT4:
13733 return new FunctionObject::unary<glw::GLdouble /* ResT */, DMat4 /* ArgT */>(function, "determinant",
13734 Math::determinant);
13736 TCU_FAIL("Not implemented");
13742 case FUNCTION_DISTANCE:
13744 switch (variable_type)
13746 case Utils::VARIABLE_TYPE_DVEC2:
13747 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
13748 function, "distance", tcu::distance);
13750 case Utils::VARIABLE_TYPE_DVEC3:
13751 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13752 function, "distance", tcu::distance);
13754 case Utils::VARIABLE_TYPE_DVEC4:
13755 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
13756 function, "distance", tcu::distance);
13766 switch (variable_type)
13768 case Utils::VARIABLE_TYPE_DVEC2:
13769 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
13770 function, "dot", tcu::dot);
13772 case Utils::VARIABLE_TYPE_DVEC3:
13773 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13774 function, "dot", tcu::dot);
13776 case Utils::VARIABLE_TYPE_DVEC4:
13777 return new FunctionObject::binary<glw::GLdouble /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
13778 function, "dot", tcu::dot);
13786 case FUNCTION_EQUAL:
13788 switch (variable_type)
13790 case Utils::VARIABLE_TYPE_DVEC2:
13791 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
13792 function, "equal", Math::equal);
13794 case Utils::VARIABLE_TYPE_DVEC3:
13795 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13796 function, "equal", Math::equal);
13798 case Utils::VARIABLE_TYPE_DVEC4:
13799 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
13800 function, "equal", Math::equal);
13808 case FUNCTION_FACEFORWARD:
13810 switch (variable_type)
13812 case Utils::VARIABLE_TYPE_DVEC2:
13813 return new FunctionObject::tenary<tcu::DVec2 /* ResT */, const tcu::DVec2& /* Arg1T */,
13814 const tcu::DVec2& /* Arg2T */, const tcu::DVec2& /* Arg3T */>(
13815 function, "faceforward", tcu::faceForward);
13817 case Utils::VARIABLE_TYPE_DVEC3:
13818 return new FunctionObject::tenary<tcu::DVec3 /* ResT */, const tcu::DVec3& /* Arg1T */,
13819 const tcu::DVec3& /* Arg2T */, const tcu::DVec3& /* Arg3T */>(
13820 function, "faceforward", tcu::faceForward);
13822 case Utils::VARIABLE_TYPE_DVEC4:
13823 return new FunctionObject::tenary<tcu::DVec4 /* ResT */, const tcu::DVec4& /* Arg1T */,
13824 const tcu::DVec4& /* Arg2T */, const tcu::DVec4& /* Arg3T */>(
13825 function, "faceforward", tcu::faceForward);
13833 case FUNCTION_FLOOR:
13835 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
13836 function, "floor", floor, variable_type /* res_type */, variable_type /* arg_type */);
13842 return new FunctionObject::tenaryByComponent(function, "fma", Math::fma, variable_type /* res_type */,
13843 variable_type /* arg1_type */, variable_type /* arg2_type */,
13844 variable_type /* arg3_type */);
13848 case FUNCTION_FRACT:
13850 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
13851 function, "fract", Math::fract, variable_type /* res_type */, variable_type /* arg_type */);
13855 case FUNCTION_FREXP:
13857 return new FunctionObject::unaryWithOutputByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* ArgT */,
13858 glw::GLint /* OutT */>(
13859 function, "frexp", Math::frexp, variable_type /* res_type */, variable_type /* arg_type */,
13860 int_type /* out_type */);
13864 case FUNCTION_GREATERTHAN:
13866 switch (variable_type)
13868 case Utils::VARIABLE_TYPE_DVEC2:
13869 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
13870 function, "greaterThan", Math::greaterThan);
13872 case Utils::VARIABLE_TYPE_DVEC3:
13873 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13874 function, "greaterThan", Math::greaterThan);
13876 case Utils::VARIABLE_TYPE_DVEC4:
13877 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
13878 function, "greaterThan", Math::greaterThan);
13886 case FUNCTION_GREATERTHANEQUAL:
13888 switch (variable_type)
13890 case Utils::VARIABLE_TYPE_DVEC2:
13891 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
13892 function, "greaterThanEqual", Math::greaterThanEqual);
13894 case Utils::VARIABLE_TYPE_DVEC3:
13895 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13896 function, "greaterThanEqual", Math::greaterThanEqual);
13898 case Utils::VARIABLE_TYPE_DVEC4:
13899 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
13900 function, "greaterThanEqual", Math::greaterThanEqual);
13908 case FUNCTION_INVERSE:
13910 switch (variable_type)
13912 case Utils::VARIABLE_TYPE_DMAT2:
13913 return new FunctionObject::unary<DMat2 /* ResT */, DMat2 /* ArgT */>(function, "inverse", Math::inverse);
13915 case Utils::VARIABLE_TYPE_DMAT3:
13916 return new FunctionObject::unary<DMat3 /* ResT */, DMat3 /* ArgT */>(function, "inverse", Math::inverse);
13918 case Utils::VARIABLE_TYPE_DMAT4:
13919 return new FunctionObject::unary<DMat4 /* ResT */, DMat4 /* ArgT */>(function, "inverse", Math::inverse);
13927 case FUNCTION_INVERSESQRT:
13929 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
13930 function, "inversesqrt", Math::inverseSqrt, variable_type /* res_type */, variable_type /* arg_type */);
13934 case FUNCTION_LDEXP:
13936 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
13937 glw::GLint /* Arg2T */>(
13938 function, "ldexp", ::ldexp, variable_type /* res_type */, variable_type /* arg1_type */,
13939 int_type /* arg2_type */);
13943 case FUNCTION_LESSTHAN:
13945 switch (variable_type)
13947 case Utils::VARIABLE_TYPE_DVEC2:
13948 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
13949 function, "lessThan", Math::lessThan);
13951 case Utils::VARIABLE_TYPE_DVEC3:
13952 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13953 function, "lessThan", Math::lessThan);
13955 case Utils::VARIABLE_TYPE_DVEC4:
13956 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
13957 function, "lessThan", Math::lessThan);
13965 case FUNCTION_LESSTHANEQUAL:
13967 switch (variable_type)
13969 case Utils::VARIABLE_TYPE_DVEC2:
13970 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
13971 function, "lessThanEqual", Math::lessThanEqual);
13973 case Utils::VARIABLE_TYPE_DVEC3:
13974 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
13975 function, "lessThanEqual", Math::lessThanEqual);
13977 case Utils::VARIABLE_TYPE_DVEC4:
13978 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
13979 function, "lessThanEqual", Math::lessThanEqual);
13987 case FUNCTION_LENGTH:
13989 switch (variable_type)
13991 case Utils::VARIABLE_TYPE_DVEC2:
13992 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec2 /* ArgT */>(function, "length",
13995 case Utils::VARIABLE_TYPE_DVEC3:
13996 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec3 /* ArgT */>(function, "length",
13999 case Utils::VARIABLE_TYPE_DVEC4:
14000 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::DVec4 /* ArgT */>(function, "length",
14009 case FUNCTION_MATRIXCOMPMULT:
14011 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14012 glw::GLdouble /* Arg2T */>(
14013 function, "matrixCompMult", Math::multiply, variable_type /* res_type */, variable_type /* arg1_type */,
14014 variable_type /* arg2_type */);
14020 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14021 glw::GLdouble /* Arg2T */>(
14022 function, "max", Math::max, variable_type /* res_type */, variable_type /* arg1_type */,
14023 variable_type /* arg2_type */);
14027 case FUNCTION_MAX_AGAINST_SCALAR:
14029 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14030 glw::GLdouble /* Arg2T */>(
14031 function, "max", Math::max, variable_type /* res_type */, variable_type /* arg1_type */,
14032 scalar_type /* arg2_type */);
14038 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14039 glw::GLdouble /* Arg2T */>(
14040 function, "min", Math::min, variable_type /* res_type */, variable_type /* arg1_type */,
14041 variable_type /* arg2_type */);
14045 case FUNCTION_MIN_AGAINST_SCALAR:
14047 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14048 glw::GLdouble /* Arg2T */>(
14049 function, "min", Math::min, variable_type /* res_type */, variable_type /* arg1_type */,
14050 scalar_type /* arg2_type */);
14056 return new FunctionObject::tenaryByComponent(function, "mix", Math::mix, variable_type /* res_type */,
14057 variable_type /* arg1_type */, variable_type /* arg2_type */,
14058 variable_type /* arg3_type */);
14064 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14065 glw::GLdouble /* Arg2T */>(
14066 function, "mod", Math::mod, variable_type /* res_type */, variable_type /* arg1_type */,
14067 variable_type /* arg2_type */);
14071 case FUNCTION_MOD_AGAINST_SCALAR:
14073 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14074 glw::GLdouble /* Arg2T */>(
14075 function, "mod", Math::mod, variable_type /* res_type */, variable_type /* arg1_type */,
14076 scalar_type /* arg2_type */);
14080 case FUNCTION_MODF:
14082 return new FunctionObject::unaryWithOutputByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* ArgT */,
14083 glw::GLdouble /* OutT */>(
14084 function, "modf", Math::modf, variable_type /* res_type */, variable_type /* arg_type */,
14085 variable_type /* out_type */);
14089 case FUNCTION_NORMALIZE:
14091 switch (variable_type)
14093 case Utils::VARIABLE_TYPE_DVEC2:
14094 return new FunctionObject::unary<tcu::DVec2 /* ResT */, tcu::DVec2 /* ArgT */>(function, "normalize",
14097 case Utils::VARIABLE_TYPE_DVEC3:
14098 return new FunctionObject::unary<tcu::DVec3 /* ResT */, tcu::DVec3 /* ArgT */>(function, "normalize",
14101 case Utils::VARIABLE_TYPE_DVEC4:
14102 return new FunctionObject::unary<tcu::DVec4 /* ResT */, tcu::DVec4 /* ArgT */>(function, "normalize",
14111 case FUNCTION_NOTEQUAL:
14113 switch (variable_type)
14115 case Utils::VARIABLE_TYPE_DVEC2:
14116 return new FunctionObject::binary<tcu::UVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14117 function, "notEqual", Math::notEqual);
14119 case Utils::VARIABLE_TYPE_DVEC3:
14120 return new FunctionObject::binary<tcu::UVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14121 function, "notEqual", Math::notEqual);
14123 case Utils::VARIABLE_TYPE_DVEC4:
14124 return new FunctionObject::binary<tcu::UVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14125 function, "notEqual", Math::notEqual);
14133 case FUNCTION_OUTERPRODUCT:
14135 switch (variable_type)
14137 case Utils::VARIABLE_TYPE_DMAT2:
14138 return new FunctionObject::binary<DMat2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14139 function, "outerProduct", Math::outerProduct);
14141 case Utils::VARIABLE_TYPE_DMAT2X3:
14142 return new FunctionObject::binary<DMat2x3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14143 function, "outerProduct", Math::outerProduct);
14145 case Utils::VARIABLE_TYPE_DMAT2X4:
14146 return new FunctionObject::binary<DMat2x4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14147 function, "outerProduct", Math::outerProduct);
14149 case Utils::VARIABLE_TYPE_DMAT3:
14150 return new FunctionObject::binary<DMat3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14151 function, "outerProduct", Math::outerProduct);
14153 case Utils::VARIABLE_TYPE_DMAT3X2:
14154 return new FunctionObject::binary<DMat3x2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14155 function, "outerProduct", Math::outerProduct);
14157 case Utils::VARIABLE_TYPE_DMAT3X4:
14158 return new FunctionObject::binary<DMat3x4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14159 function, "outerProduct", Math::outerProduct);
14161 case Utils::VARIABLE_TYPE_DMAT4:
14162 return new FunctionObject::binary<DMat4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14163 function, "outerProduct", Math::outerProduct);
14165 case Utils::VARIABLE_TYPE_DMAT4X2:
14166 return new FunctionObject::binary<DMat4x2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14167 function, "outerProduct", Math::outerProduct);
14169 case Utils::VARIABLE_TYPE_DMAT4X3:
14170 return new FunctionObject::binary<DMat4x3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14171 function, "outerProduct", Math::outerProduct);
14179 case FUNCTION_PACKDOUBLE2X32:
14181 return new FunctionObject::unary<glw::GLdouble /* ResT */, tcu::UVec2 /* ArgT */>(function, "packDouble2x32",
14182 Math::packDouble2x32);
14186 case FUNCTION_REFLECT:
14188 switch (variable_type)
14190 case Utils::VARIABLE_TYPE_DVEC2:
14191 return new FunctionObject::binary<tcu::DVec2 /* ResT */, tcu::DVec2 /* Arg1T */, tcu::DVec2 /* Arg2T */>(
14192 function, "reflect", tcu::reflect);
14194 case Utils::VARIABLE_TYPE_DVEC3:
14195 return new FunctionObject::binary<tcu::DVec3 /* ResT */, tcu::DVec3 /* Arg1T */, tcu::DVec3 /* Arg2T */>(
14196 function, "reflect", tcu::reflect);
14198 case Utils::VARIABLE_TYPE_DVEC4:
14199 return new FunctionObject::binary<tcu::DVec4 /* ResT */, tcu::DVec4 /* Arg1T */, tcu::DVec4 /* Arg2T */>(
14200 function, "reflect", tcu::reflect);
14208 case FUNCTION_REFRACT:
14210 switch (variable_type)
14212 case Utils::VARIABLE_TYPE_DVEC2:
14213 return new FunctionObject::tenary<tcu::DVec2 /* ResT */, const tcu::DVec2& /* Arg1T */,
14214 const tcu::DVec2& /* Arg2T */, glw::GLdouble /* Arg3T */>(
14215 function, "refract", tcu::refract);
14217 case Utils::VARIABLE_TYPE_DVEC3:
14218 return new FunctionObject::tenary<tcu::DVec3 /* ResT */, const tcu::DVec3& /* Arg1T */,
14219 const tcu::DVec3& /* Arg2T */, glw::GLdouble /* Arg3T */>(
14220 function, "refract", tcu::refract);
14222 case Utils::VARIABLE_TYPE_DVEC4:
14223 return new FunctionObject::tenary<tcu::DVec4 /* ResT */, const tcu::DVec4& /* Arg1T */,
14224 const tcu::DVec4& /* Arg2T */, glw::GLdouble /* Arg3T */>(
14225 function, "refract", tcu::refract);
14233 case FUNCTION_ROUND:
14235 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14236 function, "round", Math::round, variable_type /* res_type */, variable_type /* arg_type */);
14240 case FUNCTION_ROUNDEVEN:
14242 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14243 function, "roundEven", Math::roundEven, variable_type /* res_type */, variable_type /* arg_type */);
14247 case FUNCTION_SIGN:
14249 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14250 function, "sign", Math::sign, variable_type /* res_type */, variable_type /* arg_type */);
14254 case FUNCTION_SMOOTHSTEP:
14256 return new FunctionObject::tenaryByComponent(function, "smoothstep", Math::smoothStep,
14257 variable_type /* res_type */, variable_type /* arg1_type */,
14258 variable_type /* arg2_type */, variable_type /* arg3_type */);
14262 case FUNCTION_SMOOTHSTEP_AGAINST_SCALAR:
14264 return new FunctionObject::tenaryByComponent(function, "smoothstep", Math::smoothStep,
14265 variable_type /* res_type */, scalar_type /* arg1_type */,
14266 scalar_type /* arg2_type */, variable_type /* arg3_type */);
14270 case FUNCTION_SQRT:
14272 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14273 function, "sqrt", sqrt, variable_type /* res_type */, variable_type /* arg_type */);
14277 case FUNCTION_STEP:
14279 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14280 glw::GLdouble /* Arg2T */>(
14281 function, "step", Math::step, variable_type /* res_type */, variable_type /* arg1_type */,
14282 variable_type /* arg2_type */);
14286 case FUNCTION_STEP_AGAINST_SCALAR:
14288 return new FunctionObject::binaryByComponent<glw::GLdouble /* ResT */, glw::GLdouble /* Arg1T */,
14289 glw::GLdouble /* Arg2T */>(
14290 function, "step", Math::step, variable_type /* res_type */, scalar_type /* arg1_type */,
14291 variable_type /* arg2_type */);
14295 case FUNCTION_TRANSPOSE:
14297 switch (variable_type)
14299 case Utils::VARIABLE_TYPE_DMAT2:
14300 return new FunctionObject::unary<DMat2 /* ResT */, DMat2 /* ArgT */>(function, "transpose",
14303 case Utils::VARIABLE_TYPE_DMAT2X3:
14304 return new FunctionObject::unary<DMat2x3 /* ResT */, DMat3x2 /* ArgT */>(function, "transpose",
14307 case Utils::VARIABLE_TYPE_DMAT2X4:
14308 return new FunctionObject::unary<DMat2x4 /* ResT */, DMat4x2 /* ArgT */>(function, "transpose",
14311 case Utils::VARIABLE_TYPE_DMAT3:
14312 return new FunctionObject::unary<DMat3 /* ResT */, DMat3 /* ArgT */>(function, "transpose",
14315 case Utils::VARIABLE_TYPE_DMAT3X2:
14316 return new FunctionObject::unary<DMat3x2 /* ResT */, DMat2x3 /* ArgT */>(function, "transpose",
14319 case Utils::VARIABLE_TYPE_DMAT3X4:
14320 return new FunctionObject::unary<DMat3x4 /* ResT */, DMat4x3 /* ArgT */>(function, "transpose",
14323 case Utils::VARIABLE_TYPE_DMAT4:
14324 return new FunctionObject::unary<DMat4 /* ResT */, DMat4 /* ArgT */>(function, "transpose",
14327 case Utils::VARIABLE_TYPE_DMAT4X2:
14328 return new FunctionObject::unary<DMat4x2 /* ResT */, DMat2x4 /* ArgT */>(function, "transpose",
14331 case Utils::VARIABLE_TYPE_DMAT4X3:
14332 return new FunctionObject::unary<DMat4x3 /* ResT */, DMat3x4 /* ArgT */>(function, "transpose",
14341 case FUNCTION_TRUNC:
14343 return new FunctionObject::unaryByComponent<glw::GLdouble /* ResT */>(
14344 function, "trunc", Math::trunc, variable_type /* res_type */, variable_type /* arg_type */);
14348 case FUNCTION_UNPACKDOUBLE2X32:
14350 return new FunctionObject::unary<tcu::UVec2 /* ResT */, glw::GLdouble /* ArgT */>(function, "unpackDouble2x32",
14351 Math::unpackDouble2x32);
14355 case FUNCTION_ISNAN:
14357 return new FunctionObject::unaryByComponent<glw::GLuint /* ResT */>(
14358 function, "isnan", Math::isnan_impl, uint_type /* res_type */, variable_type /* arg_type */);
14362 case FUNCTION_ISINF:
14364 return new FunctionObject::unaryByComponent<glw::GLuint /* ResT */>(
14365 function, "isinf", Math::isinf_impl, uint_type /* res_type */, variable_type /* arg_type */);
14370 TCU_FAIL("Not implemented");
14375 TCU_FAIL("Not implemented");
14379 /** Get gl.uniform* that match type of argument. Assumes that type is matrix of double.
14381 * @param argument Argument index
14382 * @param function_object Function object
14384 * @return Function pointer
14386 GPUShaderFP64Test10::uniformDMatFunctionPointer GPUShaderFP64Test10::getUniformFunctionForDMat(
14387 glw::GLuint argument, const functionObject& function_object) const
14389 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14390 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14392 switch (argument_type)
14394 case Utils::VARIABLE_TYPE_DMAT2:
14395 return gl.uniformMatrix2dv;
14397 case Utils::VARIABLE_TYPE_DMAT2X3:
14398 return gl.uniformMatrix2x3dv;
14400 case Utils::VARIABLE_TYPE_DMAT2X4:
14401 return gl.uniformMatrix2x4dv;
14403 case Utils::VARIABLE_TYPE_DMAT3:
14404 return gl.uniformMatrix3dv;
14406 case Utils::VARIABLE_TYPE_DMAT3X2:
14407 return gl.uniformMatrix3x2dv;
14409 case Utils::VARIABLE_TYPE_DMAT3X4:
14410 return gl.uniformMatrix3x4dv;
14412 case Utils::VARIABLE_TYPE_DMAT4:
14413 return gl.uniformMatrix4dv;
14415 case Utils::VARIABLE_TYPE_DMAT4X2:
14416 return gl.uniformMatrix4x2dv;
14418 case Utils::VARIABLE_TYPE_DMAT4X3:
14419 return gl.uniformMatrix4x3dv;
14425 TCU_FAIL("Not implemented");
14429 /** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of double.
14431 * @param argument Argument index
14432 * @param function_object Function object
14434 * @return Function pointer
14436 GPUShaderFP64Test10::uniformDVecFunctionPointer GPUShaderFP64Test10::getUniformFunctionForDVec(
14437 glw::GLuint argument, const functionObject& function_object) const
14439 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14440 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14442 switch (argument_type)
14444 case Utils::VARIABLE_TYPE_DOUBLE:
14445 return gl.uniform1dv;
14447 case Utils::VARIABLE_TYPE_DVEC2:
14448 return gl.uniform2dv;
14450 case Utils::VARIABLE_TYPE_DVEC3:
14451 return gl.uniform3dv;
14453 case Utils::VARIABLE_TYPE_DVEC4:
14454 return gl.uniform4dv;
14457 TCU_FAIL("Not implemented");
14464 /** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of signed integer.
14466 * @param argument Argument index
14467 * @param function_object Function object
14469 * @return Function pointer
14471 GPUShaderFP64Test10::uniformIVecFunctionPointer GPUShaderFP64Test10::getUniformFunctionForIVec(
14472 glw::GLuint argument, const functionObject& function_object) const
14474 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14475 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14477 switch (argument_type)
14479 case Utils::VARIABLE_TYPE_INT:
14480 return gl.uniform1iv;
14482 case Utils::VARIABLE_TYPE_IVEC2:
14483 return gl.uniform2iv;
14485 case Utils::VARIABLE_TYPE_IVEC3:
14486 return gl.uniform3iv;
14488 case Utils::VARIABLE_TYPE_IVEC4:
14489 return gl.uniform4iv;
14492 TCU_FAIL("Not implemented");
14499 /** Get gl.uniform* that match type of argument. Assumes that type is scalar or vector of unsigned integer.
14501 * @param argument Argument index
14502 * @param function_object Function object
14504 * @return Function pointer
14506 GPUShaderFP64Test10::uniformUVecFunctionPointer GPUShaderFP64Test10::getUniformFunctionForUVec(
14507 glw::GLuint argument, const functionObject& function_object) const
14509 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
14510 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
14512 switch (argument_type)
14514 case Utils::VARIABLE_TYPE_UVEC2:
14515 return gl.uniform2uiv;
14518 TCU_FAIL("Not implemented");
14525 /** Get name of uniform that will be used as <argument>.
14527 * @param argument Argument index
14529 * @return Name of uniform
14531 const glw::GLchar* GPUShaderFP64Test10::getUniformName(glw::GLuint argument) const
14536 return "uniform_0";
14539 return "uniform_1";
14542 return "uniform_2";
14545 TCU_FAIL("Not implemented");
14551 /** Get name of varying that will be used as <result>.
14553 * @param result Result index
14555 * @return Name of varying
14557 const glw::GLchar* GPUShaderFP64Test10::getVaryingName(glw::GLuint result) const
14571 TCU_FAIL("Not implemented");
14577 /** Check if given combination of function and type is implemented
14579 * @param function Function enumeration
14580 * @param type Type details
14582 * @return true if function is available for given type, false otherwise
14584 bool GPUShaderFP64Test10::isFunctionImplemented(functionEnum function, const typeDetails& type) const
14586 static const bool look_up_table[][3] = {
14587 /* SCALAR, VECTOR, MATRIX */
14588 /* FUNCTION_ABS: */ { true, true, false },
14589 /* FUNCTION_CEIL: */ { true, true, false },
14590 /* FUNCTION_CLAMP: */ { true, true, false },
14591 /* FUNCTION_CLAMP_AGAINST_SCALAR: */ { false, true, false },
14592 /* FUNCTION_CROSS: */ { false, true, false },
14593 /* FUNCTION_DETERMINANT: */ { false, false, true },
14594 /* FUNCTION_DISTANCE: */ { false, true, false },
14595 /* FUNCTION_DOT: */ { false, true, false },
14596 /* FUNCTION_EQUAL: */ { false, true, false },
14597 /* FUNCTION_FACEFORWARD: */ { false, true, false },
14598 /* FUNCTION_FLOOR: */ { true, true, false },
14599 /* FUNCTION_FMA: */ { true, true, false },
14600 /* FUNCTION_FRACT: */ { true, true, false },
14601 /* FUNCTION_FREXP: */ { true, true, false },
14602 /* FUNCTION_GREATERTHAN: */ { false, true, false },
14603 /* FUNCTION_GREATERTHANEQUAL: */ { false, true, false },
14604 /* FUNCTION_INVERSE: */ { false, false, true },
14605 /* FUNCTION_INVERSESQRT: */ { true, true, false },
14606 /* FUNCTION_LDEXP: */ { true, true, false },
14607 /* FUNCTION_LESSTHAN: */ { false, true, false },
14608 /* FUNCTION_LESSTHANEQUAL: */ { false, true, false },
14609 /* FUNCTION_LENGTH: */ { false, true, false },
14610 /* FUNCTION_MATRIXCOMPMULT: */ { false, false, true },
14611 /* FUNCTION_MAX: */ { true, true, false },
14612 /* FUNCTION_MAX_AGAINST_SCALAR: */ { false, true, false },
14613 /* FUNCTION_MIN: */ { true, true, false },
14614 /* FUNCTION_MIN_AGAINST_SCALAR: */ { false, true, false },
14615 /* FUNCTION_MIX: */ { true, true, false },
14616 /* FUNCTION_MOD: */ { true, true, false },
14617 /* FUNCTION_MOD_AGAINST_SCALAR: */ { false, true, false },
14618 /* FUNCTION_MODF: */ { true, true, false },
14619 /* FUNCTION_NORMALIZE: */ { false, true, false },
14620 /* FUNCTION_NOTEQUAL: */ { false, true, false },
14621 /* FUNCTION_OUTERPRODUCT: */ { false, false, true },
14622 /* FUNCTION_PACKDOUBLE2X32: */ { true, false, false },
14623 /* FUNCTION_REFLECT: */ { false, true, false },
14624 /* FUNCTION_REFRACT: */ { false, true, false },
14625 /* FUNCTION_ROUND: */ { true, true, false },
14626 /* FUNCTION_ROUNDEVEN: */ { true, true, false },
14627 /* FUNCTION_SIGN: */ { true, false, false },
14628 /* FUNCTION_SMOOTHSTEP: */ { true, true, false },
14629 /* FUNCTION_SMOOTHSTEP_AGAINST_SCALAR: */ { false, true, false },
14630 /* FUNCTION_SQRT: */ { true, true, false },
14631 /* FUNCTION_STEP: */ { true, true, false },
14632 /* FUNCTION_STEP_AGAINST_SCALAR: */ { false, true, false },
14633 /* FUNCTION_TRANSPOSE: */ { false, false, false },
14634 /* FUNCTION_TRUNC: */ { true, true, false },
14635 /* FUNCTION_UNPACKDOUBLE2X32: */ { true, false, false },
14636 /* FUNCTION_ISNAN: */ { true, true, false },
14637 /* FUNCTION_ISINF: */ { true, true, false },
14640 bool result = look_up_table[function][type.m_general_type];
14642 if (true == result)
14646 case FUNCTION_CROSS: /* Only 3 element vectors */
14647 result = (3 == type.m_n_rows);
14649 case FUNCTION_DETERMINANT: /* Only square matrices */
14650 case FUNCTION_INVERSE:
14651 result = (type.m_n_columns == type.m_n_rows);
14661 /** Logs variable of given type: name (type) [values]
14663 * @param buffer Source of data
14664 * @param name Name of variable
14665 * @param type Type of variable
14667 void GPUShaderFP64Test10::logVariableType(const glw::GLvoid* buffer, const glw::GLchar* name,
14668 Utils::_variable_type type) const
14670 const Utils::_variable_type base_type = Utils::getBaseVariableType(type);
14671 const glw::GLuint n_components = Utils::getNumberOfComponentsForVariableType(type);
14672 tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
14674 message << name << " (" << Utils::getVariableTypeString(type) << ") [";
14676 for (glw::GLuint component = 0; component < n_components; ++component)
14678 if (0 != component)
14685 case Utils::VARIABLE_TYPE_DOUBLE:
14686 message << ((glw::GLdouble*)buffer)[component];
14688 case Utils::VARIABLE_TYPE_INT:
14689 message << ((glw::GLint*)buffer)[component];
14691 case Utils::VARIABLE_TYPE_UINT:
14692 message << ((glw::GLuint*)buffer)[component];
14695 TCU_FAIL("Not implemented");
14699 message << "]" << tcu::TestLog::EndMessage;
14702 /** Prepare input arguments, data are stored in <buffer>
14704 * @param function_object Function object
14705 * @param vertex Vertex index
14706 * @param buffer Buffer pointer
14708 void GPUShaderFP64Test10::prepareArgument(const functionObject& function_object, glw::GLuint vertex,
14709 glw::GLubyte* buffer)
14711 const glw::GLuint n_arguments = function_object.getArgumentCount();
14713 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
14715 const glw::GLuint offset = function_object.getArgumentOffset(argument);
14717 prepareComponents(function_object, vertex, argument, buffer + offset);
14721 /** Prepare components for given <function_object>, <vertex> and <argument>
14723 * @param function_object Function object
14724 * @param vertex Vertex index
14725 * @param argument Argument index
14726 * @param buffer Buffer pointer
14728 void GPUShaderFP64Test10::prepareComponents(const functionObject& function_object, glw::GLuint vertex,
14729 glw::GLuint argument, glw::GLubyte* buffer)
14731 glw::GLuint argument_index[3] = { 0 };
14732 glw::GLuint argument_reset[3] = { 0 };
14733 glw::GLuint argument_step[3] = { 0 };
14734 glw::GLdouble double_argument_start[3] = { 0.0 };
14735 const Utils::_variable_type base_arg_type = Utils::getBaseVariableType(function_object.getArgumentType(argument));
14736 glw::GLuint int_argument_start = -4;
14737 const glw::GLuint n_arguments = function_object.getArgumentCount();
14738 const glw::GLuint n_components = function_object.getArgumentComponents(argument);
14739 glw::GLuint uint_argument_start = 0;
14741 switch (n_arguments)
14744 argument_step[0] = 1;
14745 argument_reset[0] = 1024;
14746 double_argument_start[0] = -511.5;
14749 argument_step[0] = 32;
14750 argument_step[1] = 1;
14751 argument_reset[0] = 32;
14752 argument_reset[1] = 32;
14753 double_argument_start[0] = -15.5;
14754 double_argument_start[1] = -15.5;
14757 argument_step[0] = 64;
14758 argument_step[1] = 8;
14759 argument_step[2] = 1;
14760 argument_reset[0] = 16;
14761 argument_reset[1] = 8;
14762 argument_reset[2] = 8;
14763 double_argument_start[0] = -7.5;
14764 double_argument_start[1] = -3.5;
14765 double_argument_start[2] = -3.5;
14768 TCU_FAIL("Not implemented");
14773 switch (function_object.getFunctionEnum())
14775 case FUNCTION_CLAMP: /* arg_2 must be less than arg_3 */
14776 case FUNCTION_CLAMP_AGAINST_SCALAR:
14777 double_argument_start[2] = 4.5;
14779 case FUNCTION_INVERSESQRT: /* inversesqrt is undefined for argument <= 0 */
14780 double_argument_start[0] = 16.5;
14782 case FUNCTION_SMOOTHSTEP: /* arg_1 must be less than arg_2 */
14783 case FUNCTION_SMOOTHSTEP_AGAINST_SCALAR:
14784 argument_step[0] = 1;
14785 argument_step[1] = 8;
14786 argument_step[2] = 64;
14787 argument_reset[0] = 8;
14788 argument_reset[1] = 8;
14789 argument_reset[2] = 16;
14790 double_argument_start[0] = -3.5;
14791 double_argument_start[1] = 4.5;
14792 double_argument_start[2] = -7.5;
14798 for (glw::GLuint i = 0; i < n_arguments; ++i)
14800 argument_index[i] = (vertex / argument_step[i]) % argument_reset[i];
14803 switch (base_arg_type)
14805 case Utils::VARIABLE_TYPE_DOUBLE:
14807 glw::GLdouble* argument_dst = (glw::GLdouble*)buffer;
14809 double_argument_start[argument] += argument_index[argument];
14811 for (glw::GLuint component = 0; component < n_components; ++component)
14813 glw::GLdouble value = double_argument_start[argument] + ((glw::GLdouble)component) / 8.0;
14815 switch (function_object.getFunctionEnum())
14817 case FUNCTION_ROUND: /* Result for 0.5 depends on implementation */
14818 if (0.5 == Math::fract(value))
14827 argument_dst[component] = value;
14831 case Utils::VARIABLE_TYPE_INT:
14833 glw::GLint* argument_dst = (glw::GLint*)buffer;
14835 uint_argument_start += argument_index[argument];
14837 for (glw::GLuint component = 0; component < n_components; ++component)
14839 const glw::GLint value = int_argument_start + component;
14841 argument_dst[component] = value;
14845 case Utils::VARIABLE_TYPE_UINT:
14847 glw::GLuint* argument_dst = (glw::GLuint*)buffer;
14849 uint_argument_start += argument_index[argument];
14851 for (glw::GLuint component = 0; component < n_components; ++component)
14853 const glw::GLuint value = uint_argument_start + component;
14855 argument_dst[component] = value;
14860 TCU_FAIL("Not implemented");
14866 /** Prepare collection of function enumerations
14869 void GPUShaderFP64Test10::prepareFunctions()
14871 m_functions.push_back(FUNCTION_ABS);
14872 m_functions.push_back(FUNCTION_CEIL);
14873 m_functions.push_back(FUNCTION_CLAMP);
14874 m_functions.push_back(FUNCTION_CLAMP_AGAINST_SCALAR);
14875 m_functions.push_back(FUNCTION_CROSS);
14876 m_functions.push_back(FUNCTION_DETERMINANT);
14877 m_functions.push_back(FUNCTION_DISTANCE);
14878 m_functions.push_back(FUNCTION_DOT);
14879 m_functions.push_back(FUNCTION_EQUAL);
14880 m_functions.push_back(FUNCTION_FACEFORWARD);
14881 m_functions.push_back(FUNCTION_FLOOR);
14882 m_functions.push_back(FUNCTION_FMA);
14883 m_functions.push_back(FUNCTION_FRACT);
14884 m_functions.push_back(FUNCTION_FREXP);
14885 m_functions.push_back(FUNCTION_GREATERTHAN);
14886 m_functions.push_back(FUNCTION_GREATERTHANEQUAL);
14887 m_functions.push_back(FUNCTION_INVERSE);
14888 m_functions.push_back(FUNCTION_INVERSESQRT);
14889 m_functions.push_back(FUNCTION_LDEXP);
14890 m_functions.push_back(FUNCTION_LESSTHAN);
14891 m_functions.push_back(FUNCTION_LESSTHANEQUAL);
14892 m_functions.push_back(FUNCTION_LENGTH);
14893 m_functions.push_back(FUNCTION_MATRIXCOMPMULT);
14894 m_functions.push_back(FUNCTION_MAX);
14895 m_functions.push_back(FUNCTION_MAX_AGAINST_SCALAR);
14896 m_functions.push_back(FUNCTION_MIN);
14897 m_functions.push_back(FUNCTION_MIN_AGAINST_SCALAR);
14898 m_functions.push_back(FUNCTION_MIX);
14899 m_functions.push_back(FUNCTION_MOD);
14900 m_functions.push_back(FUNCTION_MOD_AGAINST_SCALAR);
14901 m_functions.push_back(FUNCTION_MODF);
14902 m_functions.push_back(FUNCTION_NORMALIZE);
14903 m_functions.push_back(FUNCTION_NOTEQUAL);
14904 m_functions.push_back(FUNCTION_OUTERPRODUCT);
14905 m_functions.push_back(FUNCTION_PACKDOUBLE2X32);
14906 m_functions.push_back(FUNCTION_REFLECT);
14907 m_functions.push_back(FUNCTION_REFRACT);
14908 m_functions.push_back(FUNCTION_ROUND);
14909 m_functions.push_back(FUNCTION_ROUNDEVEN);
14910 m_functions.push_back(FUNCTION_SIGN);
14911 m_functions.push_back(FUNCTION_SMOOTHSTEP);
14912 m_functions.push_back(FUNCTION_SMOOTHSTEP_AGAINST_SCALAR);
14913 m_functions.push_back(FUNCTION_SQRT);
14914 m_functions.push_back(FUNCTION_STEP);
14915 m_functions.push_back(FUNCTION_STEP_AGAINST_SCALAR);
14916 m_functions.push_back(FUNCTION_TRANSPOSE);
14917 m_functions.push_back(FUNCTION_TRUNC);
14918 m_functions.push_back(FUNCTION_UNPACKDOUBLE2X32);
14919 m_functions.push_back(FUNCTION_ISNAN);
14920 m_functions.push_back(FUNCTION_ISINF);
14923 /** Prepare programInfo for given functionObject
14925 * @param function_object Function object
14926 * @param out_program_info Program info
14928 void GPUShaderFP64Test10::prepareProgram(const functionObject& function_object, Utils::programInfo& out_program_info)
14930 const glw::GLuint n_varying_names = function_object.getResultCount();
14931 static const glw::GLchar* varying_names[3] = { getVaryingName(0), getVaryingName(1), getVaryingName(2) };
14933 prepareVertexShaderCode(function_object);
14935 out_program_info.build(0 /* cs */, 0 /* fs */, 0 /* gs */, 0 /* tcs */, 0 /* tes */, m_vertex_shader_code.c_str(),
14936 varying_names, n_varying_names);
14939 /** Prepare input data and expected results for given function object
14941 * @param function_object Function object
14943 void GPUShaderFP64Test10::prepareTestData(const functionObject& function_object)
14945 const glw::GLuint result_stride = function_object.getResultStride();
14946 const glw::GLuint result_buffer_size = result_stride * m_n_veritces;
14947 const glw::GLuint argument_stride = function_object.getArgumentStride();
14948 const glw::GLuint argument_buffer_size = m_n_veritces * argument_stride;
14950 m_argument_data.clear();
14951 m_expected_results_data.clear();
14953 m_argument_data.resize(argument_buffer_size);
14954 m_expected_results_data.resize(result_buffer_size);
14956 for (glw::GLuint vertex = 0; vertex < m_n_veritces; ++vertex)
14958 const glw::GLuint result_offset = vertex * result_stride;
14959 glw::GLdouble* result_dst = (glw::GLdouble*)&m_expected_results_data[result_offset];
14960 const glw::GLuint argument_offset = vertex * argument_stride;
14961 glw::GLubyte* argument_dst = &m_argument_data[argument_offset];
14963 prepareArgument(function_object, vertex, argument_dst);
14964 function_object.call(result_dst, argument_dst);
14968 /** Prepare collection of types
14971 void GPUShaderFP64Test10::prepareTypes()
14973 m_types.push_back(typeDetails(1 /* n_columns */, 1 /* n_rows */));
14974 m_types.push_back(typeDetails(1 /* n_columns */, 2 /* n_rows */));
14975 m_types.push_back(typeDetails(1 /* n_columns */, 3 /* n_rows */));
14976 m_types.push_back(typeDetails(1 /* n_columns */, 4 /* n_rows */));
14977 m_types.push_back(typeDetails(2 /* n_columns */, 2 /* n_rows */));
14978 m_types.push_back(typeDetails(2 /* n_columns */, 3 /* n_rows */));
14979 m_types.push_back(typeDetails(2 /* n_columns */, 4 /* n_rows */));
14980 m_types.push_back(typeDetails(3 /* n_columns */, 2 /* n_rows */));
14981 m_types.push_back(typeDetails(3 /* n_columns */, 3 /* n_rows */));
14982 m_types.push_back(typeDetails(3 /* n_columns */, 4 /* n_rows */));
14983 m_types.push_back(typeDetails(4 /* n_columns */, 2 /* n_rows */));
14984 m_types.push_back(typeDetails(4 /* n_columns */, 3 /* n_rows */));
14985 m_types.push_back(typeDetails(4 /* n_columns */, 4 /* n_rows */));
14988 /** Prepare source code of vertex shader for given function object. Result is stored in m_vertex_shader_code.
14990 * @param function_object Function object
14992 void GPUShaderFP64Test10::prepareVertexShaderCode(const functionObject& function_object)
14994 static const glw::GLchar* shader_template_code = "#version 400 core\n"
14996 "precision highp float;\n"
14998 "ARGUMENT_DEFINITION"
15000 "RESULT_DEFINITION"
15004 " RESULT_NAME = RESULT_TYPE(FUNCTION_NAME(ARGUMENT));\n"
15008 static const glw::GLchar* argument_definition_token = "ARGUMENT_DEFINITION";
15009 static const glw::GLchar* argument_token = "ARGUMENT";
15010 static const glw::GLchar* function_name_token = "FUNCTION_NAME";
15011 static const glw::GLchar* result_definition_token = "RESULT_DEFINITION";
15012 static const glw::GLchar* result_name_token = "RESULT_NAME";
15013 static const glw::GLchar* result_type_token = "RESULT_TYPE";
15014 static const glw::GLchar* uniform_name_token = "UNIFORM_NAME";
15015 static const glw::GLchar* uniform_type_token = "UNIFORM_TYPE";
15017 static const glw::GLchar* argument_definition = "uniform UNIFORM_TYPE UNIFORM_NAME;\nARGUMENT_DEFINITION";
15018 static const glw::GLchar* argument_str = ", UNIFORM_NAMEARGUMENT";
15019 static const glw::GLchar* first_argument = "UNIFORM_NAMEARGUMENT";
15020 static const glw::GLchar* result_definition = "flat out RESULT_TYPE RESULT_NAME;\nRESULT_DEFINITION";
15022 const glw::GLuint argument_definition_length = (glw::GLuint)strlen(argument_definition);
15023 const glw::GLuint first_argument_length = (glw::GLuint)strlen(first_argument);
15024 const glw::GLuint n_arguments = function_object.getArgumentCount();
15025 const glw::GLuint n_results = function_object.getResultCount();
15026 const glw::GLuint result_definition_length = (glw::GLuint)strlen(result_definition);
15027 std::string result_type = Utils::getVariableTypeString(function_object.getResultType(0));
15029 size_t search_position = 0;
15030 std::string string = shader_template_code;
15032 /* Replace ARGUMENT_DEFINITION with definitions */
15033 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
15035 Utils::_variable_type argument_type = function_object.getArgumentType(argument);
15036 const glw::GLchar* uniform_name = getUniformName(argument);
15037 std::string uniform_type = Utils::getVariableTypeString(argument_type);
15039 Utils::replaceToken(argument_definition_token, search_position, argument_definition, string);
15041 search_position -= argument_definition_length;
15043 Utils::replaceToken(uniform_type_token, search_position, uniform_type.c_str(), string);
15044 Utils::replaceToken(uniform_name_token, search_position, uniform_name, string);
15047 /* Remove ARGUMENT_DEFINITION */
15048 Utils::replaceToken(argument_definition_token, search_position, "", string);
15050 /* Replace RESULT_DEFINITION with definitions */
15051 for (glw::GLuint result = 0; result < n_results; ++result)
15053 Utils::_variable_type variable_type = function_object.getResultType(result);
15054 const glw::GLchar* varying_name = getVaryingName(result);
15055 std::string varying_type = Utils::getVariableTypeString(variable_type);
15057 Utils::replaceToken(result_definition_token, search_position, result_definition, string);
15059 search_position -= result_definition_length;
15061 Utils::replaceToken(result_type_token, search_position, varying_type.c_str(), string);
15062 Utils::replaceToken(result_name_token, search_position, varying_name, string);
15065 /* Remove RESULT_DEFINITION */
15066 Utils::replaceToken(result_definition_token, search_position, "", string);
15068 /* Replace RESULT_NAME */
15069 Utils::replaceToken(result_name_token, search_position, getVaryingName(0), string);
15071 /* Replace RESULT_TYPE */
15072 Utils::replaceToken(result_type_token, search_position, result_type.c_str(), string);
15074 /* Replace FUNCTION_NAME */
15075 Utils::replaceToken(function_name_token, search_position, function_object.getName(), string);
15077 /* Replace ARGUMENT with list of arguments */
15078 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
15080 const glw::GLchar* uniform_name = getUniformName(argument);
15084 Utils::replaceToken(argument_token, search_position, first_argument, string);
15088 Utils::replaceToken(argument_token, search_position, argument_str, string);
15091 search_position -= first_argument_length;
15093 Utils::replaceToken(uniform_name_token, search_position, uniform_name, string);
15096 for (glw::GLuint result = 1; result < n_results; ++result)
15098 const glw::GLchar* varying_name = getVaryingName(result);
15100 Utils::replaceToken(argument_token, search_position, argument_str, string);
15102 search_position -= first_argument_length;
15104 Utils::replaceToken(uniform_name_token, search_position, varying_name, string);
15107 /* Remove ARGUMENT */
15108 Utils::replaceToken(argument_token, search_position, "", string);
15110 m_vertex_shader_code = string;
15113 /** Test single function with one type
15115 * param function Function enumeration
15116 * param type Type details
15118 * @return true if test pass (or function is not available for <type>), false otherwise
15120 bool GPUShaderFP64Test10::test(functionEnum function, const typeDetails& type)
15122 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15124 /* Skip if function is not implemented for type */
15125 if (false == isFunctionImplemented(function, type))
15130 Utils::programInfo program(m_context);
15131 de::UniquePtr<functionObject> function_object(getFunctionObject(function, type));
15133 prepareProgram(*function_object, program);
15134 prepareTestData(*function_object);
15136 /* Set up program */
15137 gl.useProgram(program.m_program_object_id);
15138 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
15140 for (glw::GLuint vertex = 0; vertex < m_n_veritces; ++vertex)
15142 testBegin(*function_object, program.m_program_object_id, vertex);
15144 gl.beginTransformFeedback(GL_POINTS);
15145 GLU_EXPECT_NO_ERROR(gl.getError(), "BeginTransformFeedback");
15147 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
15148 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
15150 gl.endTransformFeedback();
15151 GLU_EXPECT_NO_ERROR(gl.getError(), "EndTransformFeedback");
15153 if (false == verifyResults(*function_object, vertex))
15162 /** Update transform feedback buffer and uniforms
15164 * @param function_object Function object
15165 * @param program_id Program object id
15166 * @param vertex Vertex index
15168 void GPUShaderFP64Test10::testBegin(const functionObject& function_object, glw::GLuint program_id, glw::GLuint vertex)
15170 const glw::GLuint arguments_stride = function_object.getArgumentStride();
15171 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15172 const glw::GLuint n_arguments = function_object.getArgumentCount();
15173 const glw::GLuint result_buffer_size = function_object.getResultStride();
15174 const glw::GLuint vertex_offset = arguments_stride * vertex;
15176 /* Update transform feedback buffer */
15177 std::vector<glw::GLubyte> transform_feedback_buffer_data;
15178 transform_feedback_buffer_data.resize(result_buffer_size);
15180 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
15181 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
15183 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, result_buffer_size, &transform_feedback_buffer_data[0],
15185 GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
15187 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_transform_feedback_buffer_id, 0 /* offset */,
15188 result_buffer_size);
15189 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
15192 gl.bindVertexArray(m_vertex_array_object_id);
15193 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
15195 for (glw::GLuint argument = 0; argument < n_arguments; ++argument)
15197 const glw::GLuint argument_offset = function_object.getArgumentOffset(argument);
15198 const Utils::_variable_type argument_type = function_object.getArgumentType(argument);
15199 const glw::GLuint n_columns = Utils::getNumberOfColumnsForVariableType(argument_type);
15200 const glw::GLchar* uniform_name = getUniformName(argument);
15201 const glw::GLint uniform_location = gl.getUniformLocation(program_id, uniform_name);
15202 const glw::GLdouble* uniform_src = (glw::GLdouble*)&m_argument_data[vertex_offset + argument_offset];
15204 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
15206 if (-1 == uniform_location)
15208 TCU_FAIL("Inactive uniform");
15211 if (1 == n_columns)
15213 switch (Utils::getBaseVariableType(argument_type))
15215 case Utils::VARIABLE_TYPE_DOUBLE:
15217 uniformDVecFunctionPointer p_uniform_function = getUniformFunctionForDVec(argument, function_object);
15219 p_uniform_function(uniform_location, 1 /* count */, uniform_src);
15222 case Utils::VARIABLE_TYPE_UINT:
15224 uniformUVecFunctionPointer p_uniform_function = getUniformFunctionForUVec(argument, function_object);
15226 p_uniform_function(uniform_location, 1 /* count */, (glw::GLuint*)uniform_src);
15229 case Utils::VARIABLE_TYPE_INT:
15231 uniformIVecFunctionPointer p_uniform_function = getUniformFunctionForIVec(argument, function_object);
15233 p_uniform_function(uniform_location, 1 /* count */, (glw::GLint*)uniform_src);
15237 TCU_FAIL("Not implemented");
15243 uniformDMatFunctionPointer p_uniform_function = getUniformFunctionForDMat(argument, function_object);
15245 p_uniform_function(uniform_location, 1 /* count */, GL_FALSE /* transpose */, uniform_src);
15250 /** Init GL obejcts
15253 void GPUShaderFP64Test10::testInit()
15255 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15257 prepareFunctions();
15260 gl.genBuffers(1, &m_transform_feedback_buffer_id);
15261 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
15263 gl.genVertexArrays(1, &m_vertex_array_object_id);
15264 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
15266 gl.enable(GL_RASTERIZER_DISCARD);
15269 /** Compare contents of transform feedback buffer with expected results
15271 * @param function_object Function object
15272 * @param vertex Vertex index
15274 * @return true if all results are as expected, false otherwise
15276 bool GPUShaderFP64Test10::verifyResults(const functionObject& function_object, glw::GLuint vertex)
15278 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
15279 bool test_result = true;
15280 const glw::GLuint n_results = function_object.getResultCount();
15281 const glw::GLuint results_stride = function_object.getResultStride();
15282 const glw::GLuint results_offset = vertex * results_stride;
15283 const glw::GLubyte* expected_results = &m_expected_results_data[results_offset];
15285 /* Get transform feedback data */
15286 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transform_feedback_buffer_id);
15287 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
15289 glw::GLubyte* feedback_data = (glw::GLubyte*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
15290 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
15292 for (glw::GLuint result = 0; result < n_results; ++result)
15294 const Utils::_variable_type result_type = function_object.getResultType(result);
15295 const glw::GLuint result_offset = function_object.getResultOffset(result);
15297 const glw::GLvoid* expected_result_src = expected_results + result_offset;
15298 const glw::GLvoid* result_src = feedback_data + result_offset;
15300 if (false == compare(result_type, expected_result_src, result_src))
15302 test_result = false;
15307 /* Unmap transform feedback buffer */
15308 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
15309 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
15311 if (false == test_result)
15313 const glw::GLuint argument_stride = function_object.getArgumentStride();
15314 const glw::GLuint arguments_offset = vertex * argument_stride;
15316 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Error. Invalid result."
15317 << tcu::TestLog::EndMessage;
15319 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function: " << function_object.getName()
15320 << tcu::TestLog::EndMessage;
15322 for (glw::GLuint result = 0; result < n_results; ++result)
15324 const Utils::_variable_type result_type = function_object.getResultType(result);
15325 const glw::GLuint result_offset = function_object.getResultOffset(result);
15327 const glw::GLvoid* expected_result_src = expected_results + result_offset;
15328 const glw::GLvoid* result_src = feedback_data + result_offset;
15330 logVariableType(result_src, "Result", result_type);
15331 logVariableType(expected_result_src, "Expected result", result_type);
15334 for (glw::GLuint argument = 0; argument < function_object.getArgumentCount(); ++argument)
15336 const glw::GLuint argument_offset = function_object.getArgumentOffset(argument);
15337 const glw::GLubyte* argument_src = &m_argument_data[arguments_offset + argument_offset];
15339 logVariableType(argument_src, "Argument", function_object.getArgumentType(argument));
15342 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader:\n"
15343 << m_vertex_shader_code << tcu::TestLog::EndMessage;
15346 return test_result;
15351 * @param context Rendering context.
15353 GPUShaderFP64Tests::GPUShaderFP64Tests(deqp::Context& context)
15354 : TestCaseGroup(context, "gpu_shader_fp64", "Verifies \"gpu_shader_fp64\" functionality")
15356 /* Left blank on purpose */
15359 /** Initializes a texture_storage_multisample test group.
15362 void GPUShaderFP64Tests::init(void)
15364 addChild(new GPUShaderFP64Test1(m_context));
15365 addChild(new GPUShaderFP64Test2(m_context));
15366 addChild(new GPUShaderFP64Test3(m_context));
15367 addChild(new GPUShaderFP64Test4(m_context));
15368 addChild(new GPUShaderFP64Test5(m_context));
15369 addChild(new GPUShaderFP64Test6(m_context));
15370 addChild(new GPUShaderFP64Test7(m_context));
15371 addChild(new GPUShaderFP64Test8(m_context));
15372 addChild(new GPUShaderFP64Test9(m_context));
15373 addChild(new GPUShaderFP64Test10(m_context));
15376 } /* glcts namespace */