1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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.
21 * \brief Rbo state query tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es2fShaderStateQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es2fApiCase.hpp"
27 #include "gluRenderContext.hpp"
28 #include "gluShaderProgram.hpp"
29 #include "glwEnums.hpp"
30 #include "glwFunctions.hpp"
31 #include "deRandom.hpp"
35 using namespace glw; // GLint and other GL types
36 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
47 static const char* commonTestVertSource = "void main (void)\n"
49 " gl_Position = vec4(0.0);\n"
51 static const char* commonTestFragSource = "void main (void)\n"
53 " gl_FragColor = vec4(0.0);\n"
56 static const char* brokenShader = "broken, this should not compile!\n"
61 T roundGLfloatToNearestIntegerUp (GLfloat val)
63 return (T)(ceil(val));
68 T roundGLfloatToNearestIntegerDown (GLfloat val)
70 return (T)(floor(val));
73 bool checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
79 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
80 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
81 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
87 void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected)
93 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
94 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
95 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
99 void verifyShaderParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint shader, GLenum pname, GLenum reference)
101 StateQueryMemoryWriteGuard<GLint> state;
102 gl.glGetShaderiv(shader, pname, &state);
104 if (state.verifyValidity(testCtx))
105 checkIntEquals(testCtx, state, reference);
108 bool verifyProgramParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLenum pname, GLenum reference)
110 StateQueryMemoryWriteGuard<GLint> state;
111 gl.glGetProgramiv(program, pname, &state);
113 if (state.verifyValidity(testCtx))
114 return checkIntEquals(testCtx, state, reference);
118 void verifyCurrentVertexAttribf (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
122 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
123 gl.glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
125 attribValue.verifyValidity(testCtx);
127 if (attribValue[0] != x || attribValue[1] != y || attribValue[2] != z || attribValue[3] != w)
129 testCtx.getLog() << TestLog::Message
130 << "// ERROR: Expected [" << x << "," << y << "," << z << "," << w << "];"
131 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]"
132 << TestLog::EndMessage;
133 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
134 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
138 void verifyCurrentVertexAttribConversion (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
142 StateQueryMemoryWriteGuard<GLint[4]> attribValue;
143 gl.glGetVertexAttribiv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
145 attribValue.verifyValidity(testCtx);
147 const GLint referenceAsGLintMin[] =
149 roundGLfloatToNearestIntegerDown<GLint>(x),
150 roundGLfloatToNearestIntegerDown<GLint>(y),
151 roundGLfloatToNearestIntegerDown<GLint>(z),
152 roundGLfloatToNearestIntegerDown<GLint>(w)
154 const GLint referenceAsGLintMax[] =
156 roundGLfloatToNearestIntegerUp<GLint>(x),
157 roundGLfloatToNearestIntegerUp<GLint>(y),
158 roundGLfloatToNearestIntegerUp<GLint>(z),
159 roundGLfloatToNearestIntegerUp<GLint>(w)
162 if (attribValue[0] < referenceAsGLintMin[0] || attribValue[0] > referenceAsGLintMax[0] ||
163 attribValue[1] < referenceAsGLintMin[1] || attribValue[1] > referenceAsGLintMax[1] ||
164 attribValue[2] < referenceAsGLintMin[2] || attribValue[2] > referenceAsGLintMax[2] ||
165 attribValue[3] < referenceAsGLintMin[3] || attribValue[3] > referenceAsGLintMax[3])
167 testCtx.getLog() << TestLog::Message
168 << "// ERROR: expected in range "
169 << "[" << referenceAsGLintMin[0] << " " << referenceAsGLintMax[0] << "], "
170 << "[" << referenceAsGLintMin[1] << " " << referenceAsGLintMax[1] << "], "
171 << "[" << referenceAsGLintMin[2] << " " << referenceAsGLintMax[2] << "], "
172 << "[" << referenceAsGLintMin[3] << " " << referenceAsGLintMax[3] << "]"
174 << attribValue[0] << ", "
175 << attribValue[1] << ", "
176 << attribValue[2] << ", "
177 << attribValue[3] << " "
182 << w << " " << TestLog::EndMessage;
184 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
185 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid attribute value");
189 void verifyVertexAttrib (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLint index, GLenum pname, GLenum reference)
191 StateQueryMemoryWriteGuard<GLint> state;
192 gl.glGetVertexAttribiv(index, pname, &state);
194 if (state.verifyValidity(testCtx))
195 checkIntEquals(testCtx, state, reference);
198 void verifyUniformValue1f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x)
202 StateQueryMemoryWriteGuard<GLfloat[1]> state;
203 gl.glGetUniformfv(program, location, state);
205 if (!state.verifyValidity(testCtx))
210 testCtx.getLog() << TestLog::Message
211 << "// ERROR: expected ["
216 << TestLog::EndMessage;
218 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
219 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
223 void verifyUniformValue2f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y)
227 StateQueryMemoryWriteGuard<GLfloat[2]> state;
228 gl.glGetUniformfv(program, location, state);
230 if (!state.verifyValidity(testCtx))
236 testCtx.getLog() << TestLog::Message
237 << "// ERROR: expected ["
244 << TestLog::EndMessage;
246 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
247 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
251 void verifyUniformValue3f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z)
255 StateQueryMemoryWriteGuard<GLfloat[3]> state;
256 gl.glGetUniformfv(program, location, state);
258 if (!state.verifyValidity(testCtx))
265 testCtx.getLog() << TestLog::Message
266 << "// ERROR: expected ["
275 << TestLog::EndMessage;
277 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
278 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
282 void verifyUniformValue4f (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, float x, float y, float z, float w)
286 StateQueryMemoryWriteGuard<GLfloat[4]> state;
287 gl.glGetUniformfv(program, location, state);
289 if (!state.verifyValidity(testCtx))
297 testCtx.getLog() << TestLog::Message
298 << "// ERROR: expected ["
309 << TestLog::EndMessage;
311 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
312 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
316 void verifyUniformValue1i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x)
320 StateQueryMemoryWriteGuard<GLint[1]> state;
321 gl.glGetUniformiv(program, location, state);
323 if (!state.verifyValidity(testCtx))
328 testCtx.getLog() << TestLog::Message
329 << "// ERROR: expected ["
334 << TestLog::EndMessage;
336 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
337 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
341 void verifyUniformValue2i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y)
345 StateQueryMemoryWriteGuard<GLint[2]> state;
346 gl.glGetUniformiv(program, location, state);
348 if (!state.verifyValidity(testCtx))
354 testCtx.getLog() << TestLog::Message
355 << "// ERROR: expected ["
362 << TestLog::EndMessage;
364 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
365 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
369 void verifyUniformValue3i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z)
373 StateQueryMemoryWriteGuard<GLint[3]> state;
374 gl.glGetUniformiv(program, location, state);
376 if (!state.verifyValidity(testCtx))
383 testCtx.getLog() << TestLog::Message
384 << "// ERROR: expected ["
393 << TestLog::EndMessage;
395 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
396 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
400 void verifyUniformValue4i (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w)
404 StateQueryMemoryWriteGuard<GLint[4]> state;
405 gl.glGetUniformiv(program, location, state);
407 if (!state.verifyValidity(testCtx))
415 testCtx.getLog() << TestLog::Message
416 << "// ERROR: expected ["
427 << TestLog::EndMessage;
429 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
430 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
435 void verifyUniformValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values)
439 StateQueryMemoryWriteGuard<GLfloat[Count]> state;
440 gl.glGetUniformfv(program, location, state);
442 if (!state.verifyValidity(testCtx))
445 for (int ndx = 0; ndx < Count; ++ndx)
447 if (values[ndx] != state[ndx])
449 testCtx.getLog() << TestLog::Message << "// ERROR: at index " << ndx << " expected " << values[ndx] << "; got " << state[ndx] << TestLog::EndMessage;
451 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
452 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
458 void verifyUniformMatrixValues (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLuint program, GLint location, const GLfloat* values, bool transpose)
462 StateQueryMemoryWriteGuard<GLfloat[N*N]> state;
463 gl.glGetUniformfv(program, location, state);
465 if (!state.verifyValidity(testCtx))
468 for (int y = 0; y < N; ++y)
469 for (int x = 0; x < N; ++x)
471 const int refIndex = y*N + x;
472 const int stateIndex = transpose ? (x*N + y) : (y*N + x);
474 if (values[refIndex] != state[stateIndex])
476 testCtx.getLog() << TestLog::Message << "// ERROR: at index [" << y << "][" << x << "] expected " << values[refIndex] << "; got " << state[stateIndex] << TestLog::EndMessage;
478 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
479 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid uniform value");
484 void requireShaderCompiler (tcu::TestContext& testCtx, glu::CallLogWrapper& gl)
486 StateQueryMemoryWriteGuard<GLboolean> state;
487 gl.glGetBooleanv(GL_SHADER_COMPILER, &state);
489 if (!state.verifyValidity(testCtx) || state != GL_TRUE)
490 throw tcu::NotSupportedError("Test requires SHADER_COMPILER = TRUE");
493 class ShaderTypeCase : public ApiCase
496 ShaderTypeCase (Context& context, const char* name, const char* description)
497 : ApiCase(context, name, description)
503 const GLenum shaderTypes[] = {GL_VERTEX_SHADER, GL_FRAGMENT_SHADER};
504 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
506 const GLuint shader = glCreateShader(shaderTypes[ndx]);
507 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_TYPE, shaderTypes[ndx]);
508 glDeleteShader(shader);
513 class ShaderCompileStatusCase : public ApiCase
516 ShaderCompileStatusCase (Context& context, const char* name, const char* description)
517 : ApiCase(context, name, description)
523 requireShaderCompiler(m_testCtx, *this);
525 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
526 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
528 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_FALSE);
529 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE);
531 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
532 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
534 glCompileShader(shaderVert);
535 glCompileShader(shaderFrag);
536 expectError(GL_NO_ERROR);
538 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
539 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
541 glDeleteShader(shaderVert);
542 glDeleteShader(shaderFrag);
543 expectError(GL_NO_ERROR);
547 class ShaderInfoLogCase : public ApiCase
550 ShaderInfoLogCase (Context& context, const char* name, const char* description)
551 : ApiCase(context, name, description)
557 requireShaderCompiler(m_testCtx, *this);
561 // INFO_LOG_LENGTH is 0 by default and it includes null-terminator
562 const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
563 verifyShaderParam(m_testCtx, *this, shader, GL_INFO_LOG_LENGTH, 0);
565 glShaderSource(shader, 1, &brokenShader, DE_NULL);
566 glCompileShader(shader);
567 expectError(GL_NO_ERROR);
569 // check the log length
570 StateQueryMemoryWriteGuard<GLint> logLength;
571 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
572 if (!logLength.verifyValidity(m_testCtx))
574 glDeleteShader(shader);
579 glDeleteShader(shader);
585 char buffer[2048] = {'x'}; // non-zero initialization
587 GLint written = 0; // written does not include null terminator
588 glGetShaderInfoLog(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
590 // check lengths are consistent
591 if (logLength <= DE_LENGTH_OF_ARRAY(buffer))
593 if (written != logLength-1)
595 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << logLength-1 << "; got " << written << TestLog::EndMessage;
596 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
597 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
601 // check null-terminator, either at end of buffer or at buffer[written]
602 const char* terminator = &buffer[DE_LENGTH_OF_ARRAY(buffer) - 1];
603 if (logLength < DE_LENGTH_OF_ARRAY(buffer))
604 terminator = &buffer[written];
606 if (*terminator != '\0')
608 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)*terminator << TestLog::EndMessage;
609 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
610 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
614 // check with too small buffer
616 char buffer[2048] = {'x'}; // non-zero initialization
618 // check string always ends with \0, even with small buffers
620 glGetShaderInfoLog(shader, 1, &written, buffer);
623 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length 0; got " << written << TestLog::EndMessage;
624 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
625 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
627 if (buffer[0] != '\0')
629 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator, got " << (int)buffer[0] << TestLog::EndMessage;
630 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
631 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log terminator");
635 glDeleteShader(shader);
636 expectError(GL_NO_ERROR);
640 class ShaderSourceCase : public ApiCase
643 ShaderSourceCase (Context& context, const char* name, const char* description)
644 : ApiCase(context, name, description)
650 requireShaderCompiler(m_testCtx, *this);
654 // SHADER_SOURCE_LENGTH does include 0-terminator
655 const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
656 verifyShaderParam(m_testCtx, *this, shader, GL_SHADER_SOURCE_LENGTH, 0);
658 // check the SHADER_SOURCE_LENGTH
660 glShaderSource(shader, 1, &brokenShader, DE_NULL);
661 expectError(GL_NO_ERROR);
663 StateQueryMemoryWriteGuard<GLint> sourceLength;
664 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);
666 sourceLength.verifyValidity(m_testCtx);
668 const GLint referenceLength = (GLint)std::string(brokenShader).length() + 1; // including the null terminator
669 if (sourceLength != referenceLength)
671 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage;
672 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
673 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
677 // check the concat source SHADER_SOURCE_LENGTH
679 const char* shaders[] = {brokenShader, brokenShader};
680 glShaderSource(shader, 2, shaders, DE_NULL);
681 expectError(GL_NO_ERROR);
683 StateQueryMemoryWriteGuard<GLint> sourceLength;
684 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLength);
686 sourceLength.verifyValidity(m_testCtx);
688 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length() + 1; // including the null terminator
689 if (sourceLength != referenceLength)
691 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected length " << referenceLength << "; got " << sourceLength << TestLog::EndMessage;
692 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
693 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
697 // check the string length
699 char buffer[2048] = {'x'};
700 DE_ASSERT(DE_LENGTH_OF_ARRAY(buffer) > 2 * (int)std::string(brokenShader).length());
702 GLint written = 0; // not inluding null-terminator
703 glGetShaderSource(shader, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
705 const GLint referenceLength = 2 * (GLint)std::string(brokenShader).length();
706 if (written != referenceLength)
708 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length " << referenceLength << "; got " << written << TestLog::EndMessage;
709 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
710 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
712 // check null pointer at
715 if (buffer[referenceLength] != '\0')
717 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator at " << referenceLength << TestLog::EndMessage;
718 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
719 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "did not get a null terminator");
724 // check with small buffer
726 char buffer[2048] = {'x'};
729 glGetShaderSource(shader, 1, &written, buffer);
733 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage;
734 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
735 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid source length");
737 if (buffer[0] != '\0')
739 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected null terminator; got=" << int(buffer[0]) << ", char=" << buffer[0] << TestLog::EndMessage;
740 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
741 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid terminator");
745 glDeleteShader(shader);
746 expectError(GL_NO_ERROR);
750 class DeleteStatusCase : public ApiCase
753 DeleteStatusCase (Context& context, const char* name, const char* description)
754 : ApiCase(context, name, description)
760 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
761 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
763 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
764 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
766 glCompileShader(shaderVert);
767 glCompileShader(shaderFrag);
768 expectError(GL_NO_ERROR);
770 verifyShaderParam(m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
771 verifyShaderParam(m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
773 GLuint shaderProg = glCreateProgram();
774 glAttachShader(shaderProg, shaderVert);
775 glAttachShader(shaderProg, shaderFrag);
776 glLinkProgram(shaderProg);
777 expectError(GL_NO_ERROR);
779 verifyProgramParam (m_testCtx, *this, shaderProg, GL_LINK_STATUS, GL_TRUE);
781 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_FALSE);
782 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_FALSE);
783 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_FALSE);
784 expectError(GL_NO_ERROR);
786 glUseProgram(shaderProg);
788 glDeleteShader(shaderVert);
789 glDeleteShader(shaderFrag);
790 glDeleteProgram(shaderProg);
791 expectError(GL_NO_ERROR);
793 verifyShaderParam (m_testCtx, *this, shaderVert, GL_DELETE_STATUS, GL_TRUE);
794 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_DELETE_STATUS, GL_TRUE);
795 verifyProgramParam (m_testCtx, *this, shaderProg, GL_DELETE_STATUS, GL_TRUE);
796 expectError(GL_NO_ERROR);
799 expectError(GL_NO_ERROR);
803 class CurrentVertexAttribInitialCase : public ApiCase
806 CurrentVertexAttribInitialCase (Context& context, const char* name, const char* description)
807 : ApiCase(context, name, description)
815 int attribute_count = 16;
816 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
820 for (int index = 0; index < attribute_count; ++index)
822 StateQueryMemoryWriteGuard<GLfloat[4]> attribValue;
823 glGetVertexAttribfv(index, GL_CURRENT_VERTEX_ATTRIB, attribValue);
824 attribValue.verifyValidity(m_testCtx);
826 if (attribValue[0] != 0.0f || attribValue[1] != 0.0f || attribValue[2] != 0.0f || attribValue[3] != 1.0f)
828 m_testCtx.getLog() << TestLog::Message
829 << "// ERROR: Expected [0, 0, 0, 1];"
830 << "got [" << attribValue[0] << "," << attribValue[1] << "," << attribValue[2] << "," << attribValue[3] << "]"
831 << TestLog::EndMessage;
832 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
833 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid attribute value");
839 class CurrentVertexAttribFloatCase : public ApiCase
842 CurrentVertexAttribFloatCase (Context& context, const char* name, const char* description)
843 : ApiCase(context, name, description)
851 de::Random rnd(0xabcdef);
853 int attribute_count = 16;
854 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
856 // test write float/read float
858 for (int index = 0; index < attribute_count; ++index)
860 const GLfloat x = rnd.getFloat(-64000, 64000);
861 const GLfloat y = rnd.getFloat(-64000, 64000);
862 const GLfloat z = rnd.getFloat(-64000, 64000);
863 const GLfloat w = rnd.getFloat(-64000, 64000);
865 glVertexAttrib4f(index, x, y, z, w);
866 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
868 for (int index = 0; index < attribute_count; ++index)
870 const GLfloat x = rnd.getFloat(-64000, 64000);
871 const GLfloat y = rnd.getFloat(-64000, 64000);
872 const GLfloat z = rnd.getFloat(-64000, 64000);
873 const GLfloat w = 1.0f;
875 glVertexAttrib3f(index, x, y, z);
876 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
878 for (int index = 0; index < attribute_count; ++index)
880 const GLfloat x = rnd.getFloat(-64000, 64000);
881 const GLfloat y = rnd.getFloat(-64000, 64000);
882 const GLfloat z = 0.0f;
883 const GLfloat w = 1.0f;
885 glVertexAttrib2f(index, x, y);
886 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
888 for (int index = 0; index < attribute_count; ++index)
890 const GLfloat x = rnd.getFloat(-64000, 64000);
891 const GLfloat y = 0.0f;
892 const GLfloat z = 0.0f;
893 const GLfloat w = 1.0f;
895 glVertexAttrib1f(index, x);
896 verifyCurrentVertexAttribf(m_testCtx, *this, index, x, y, z, w);
901 class CurrentVertexAttribConversionCase : public ApiCase
904 CurrentVertexAttribConversionCase (Context& context, const char* name, const char* description)
905 : ApiCase(context, name, description)
913 de::Random rnd(0xabcdef);
915 int attribute_count = 16;
916 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribute_count);
918 // test write float/read float
920 for (int index = 0; index < attribute_count; ++index)
922 const GLfloat x = rnd.getFloat(-64000, 64000);
923 const GLfloat y = rnd.getFloat(-64000, 64000);
924 const GLfloat z = rnd.getFloat(-64000, 64000);
925 const GLfloat w = rnd.getFloat(-64000, 64000);
927 glVertexAttrib4f(index, x, y, z, w);
928 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
930 for (int index = 0; index < attribute_count; ++index)
932 const GLfloat x = rnd.getFloat(-64000, 64000);
933 const GLfloat y = rnd.getFloat(-64000, 64000);
934 const GLfloat z = rnd.getFloat(-64000, 64000);
935 const GLfloat w = 1.0f;
937 glVertexAttrib3f(index, x, y, z);
938 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
940 for (int index = 0; index < attribute_count; ++index)
942 const GLfloat x = rnd.getFloat(-64000, 64000);
943 const GLfloat y = rnd.getFloat(-64000, 64000);
944 const GLfloat z = 0.0f;
945 const GLfloat w = 1.0f;
947 glVertexAttrib2f(index, x, y);
948 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
950 for (int index = 0; index < attribute_count; ++index)
952 const GLfloat x = rnd.getFloat(-64000, 64000);
953 const GLfloat y = 0.0f;
954 const GLfloat z = 0.0f;
955 const GLfloat w = 1.0f;
957 glVertexAttrib1f(index, x);
958 verifyCurrentVertexAttribConversion(m_testCtx, *this, index, x, y, z, w);
963 class ProgramInfoLogCase : public ApiCase
966 ProgramInfoLogCase (Context& context, const char* name, const char* description)
967 : ApiCase(context, name, description)
975 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
976 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
978 glShaderSource(shaderVert, 1, &brokenShader, DE_NULL);
979 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL);
981 glCompileShader(shaderVert);
982 glCompileShader(shaderFrag);
983 expectError(GL_NO_ERROR);
985 GLuint program = glCreateProgram();
986 glAttachShader(program, shaderVert);
987 glAttachShader(program, shaderFrag);
988 glLinkProgram(program);
990 // check INFO_LOG_LENGTH == GetProgramInfoLog len
992 char buffer[2048] = {'x'};
995 glGetProgramInfoLog(program, DE_LENGTH_OF_ARRAY(buffer), &written, buffer);
997 StateQueryMemoryWriteGuard<GLint> logLength;
998 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
999 logLength.verifyValidity(m_testCtx);
1001 if (logLength != 0 && written+1 != logLength) // INFO_LOG_LENGTH contains 0-terminator
1003 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected INFO_LOG_LENGTH " << written+1 << "; got " << logLength << TestLog::EndMessage;
1004 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1005 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
1009 // check GetProgramInfoLog works with too small buffer
1011 char buffer[2048] = {'x'};
1014 glGetProgramInfoLog(program, 1, &written, buffer);
1018 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected write length 0; got " << written << TestLog::EndMessage;
1019 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1020 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid log length");
1024 glDeleteShader(shaderVert);
1025 glDeleteShader(shaderFrag);
1026 glDeleteProgram(program);
1027 expectError(GL_NO_ERROR);
1031 class ProgramValidateStatusCase : public ApiCase
1034 ProgramValidateStatusCase (Context& context, const char* name, const char* description)
1035 : ApiCase(context, name, description)
1043 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1044 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1046 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1047 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
1049 glCompileShader(shaderVert);
1050 glCompileShader(shaderFrag);
1051 expectError(GL_NO_ERROR);
1053 GLuint program = glCreateProgram();
1054 glAttachShader(program, shaderVert);
1055 glAttachShader(program, shaderFrag);
1056 glLinkProgram(program);
1057 expectError(GL_NO_ERROR);
1059 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1060 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_TRUE);
1061 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE);
1063 glValidateProgram(program);
1064 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_TRUE);
1066 glDeleteShader(shaderVert);
1067 glDeleteShader(shaderFrag);
1068 glDeleteProgram(program);
1069 expectError(GL_NO_ERROR);
1072 // test with broken shader
1074 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1075 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1077 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1078 glShaderSource(shaderFrag, 1, &brokenShader, DE_NULL);
1080 glCompileShader(shaderVert);
1081 glCompileShader(shaderFrag);
1082 expectError(GL_NO_ERROR);
1084 GLuint program = glCreateProgram();
1085 glAttachShader(program, shaderVert);
1086 glAttachShader(program, shaderFrag);
1087 glLinkProgram(program);
1088 expectError(GL_NO_ERROR);
1090 verifyShaderParam (m_testCtx, *this, shaderVert, GL_COMPILE_STATUS, GL_TRUE);
1091 verifyShaderParam (m_testCtx, *this, shaderFrag, GL_COMPILE_STATUS, GL_FALSE);
1092 verifyProgramParam (m_testCtx, *this, program, GL_LINK_STATUS, GL_FALSE);
1094 glValidateProgram(program);
1095 verifyProgramParam(m_testCtx, *this, program, GL_VALIDATE_STATUS, GL_FALSE);
1097 glDeleteShader(shaderVert);
1098 glDeleteShader(shaderFrag);
1099 glDeleteProgram(program);
1100 expectError(GL_NO_ERROR);
1105 class ProgramAttachedShadersCase : public ApiCase
1108 ProgramAttachedShadersCase (Context& context, const char* name, const char* description)
1109 : ApiCase(context, name, description)
1117 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1118 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1120 glShaderSource(shaderVert, 1, &commonTestVertSource, DE_NULL);
1121 glShaderSource(shaderFrag, 1, &commonTestFragSource, DE_NULL);
1123 glCompileShader(shaderVert);
1124 glCompileShader(shaderFrag);
1125 expectError(GL_NO_ERROR);
1127 // check ATTACHED_SHADERS
1129 GLuint program = glCreateProgram();
1130 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 0);
1131 expectError(GL_NO_ERROR);
1133 glAttachShader(program, shaderVert);
1134 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 1);
1135 expectError(GL_NO_ERROR);
1137 glAttachShader(program, shaderFrag);
1138 verifyProgramParam(m_testCtx, *this, program, GL_ATTACHED_SHADERS, 2);
1139 expectError(GL_NO_ERROR);
1141 // check GetAttachedShaders
1143 GLuint shaders[2] = {0, 0};
1145 glGetAttachedShaders(program, DE_LENGTH_OF_ARRAY(shaders), &count, shaders);
1149 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 2; got " << count << TestLog::EndMessage;
1150 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1151 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1153 // shaders are the attached shaders?
1154 if (!((shaders[0] == shaderVert && shaders[1] == shaderFrag) ||
1155 (shaders[0] == shaderFrag && shaders[1] == shaderVert)))
1157 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected {" << shaderVert << ", " << shaderFrag << "}; got {" << shaders[0] << ", " << shaders[1] << "}" << TestLog::EndMessage;
1158 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1159 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1163 // check GetAttachedShaders with too small buffer
1165 GLuint shaders[2] = {0, 0};
1168 glGetAttachedShaders(program, 0, &count, shaders);
1171 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0; got " << count << TestLog::EndMessage;
1172 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1173 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1177 glGetAttachedShaders(program, 1, &count, shaders);
1180 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 1; got " << count << TestLog::EndMessage;
1181 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1182 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong shader count");
1186 glDeleteShader(shaderVert);
1187 glDeleteShader(shaderFrag);
1188 glDeleteProgram(program);
1189 expectError(GL_NO_ERROR);
1193 class ProgramActiveUniformNameCase : public ApiCase
1196 ProgramActiveUniformNameCase (Context& context, const char* name, const char* description)
1197 : ApiCase(context, name, description)
1205 static const char* testVertSource =
1206 "uniform highp float uniformNameWithLength23;\n"
1207 "uniform highp vec2 uniformVec2;\n"
1208 "uniform highp mat4 uniformMat4;\n"
1209 "void main (void)\n"
1211 " gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n"
1213 static const char* testFragSource =
1215 "void main (void)\n"
1217 " gl_FragColor = vec4(0.0);\n"
1220 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1221 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1223 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
1224 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
1226 glCompileShader(shaderVert);
1227 glCompileShader(shaderFrag);
1228 expectError(GL_NO_ERROR);
1230 GLuint program = glCreateProgram();
1231 glAttachShader(program, shaderVert);
1232 glAttachShader(program, shaderFrag);
1233 glLinkProgram(program);
1234 expectError(GL_NO_ERROR);
1236 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORMS, 3);
1237 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, (GLint)std::string("uniformNameWithLength23").length() + 1); // including a null terminator
1238 expectError(GL_NO_ERROR);
1240 const char* uniformNames[] =
1242 "uniformNameWithLength23",
1248 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformNames); ++ndx)
1250 char buffer[2048] = {'x'};
1251 char* bufferEnd = (buffer + 1);
1253 GLint written = 0; // null terminator not included
1256 glGetActiveUniform(program, ndx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
1258 if (written < DE_LENGTH_OF_ARRAY(buffer))
1259 bufferEnd = &buffer[written];
1261 // find matching uniform
1263 const std::string uniformName(buffer, bufferEnd);
1266 for (int uniformNdx = 0; uniformNdx < DE_LENGTH_OF_ARRAY(uniformNames); ++uniformNdx)
1268 if (uniformName == uniformNames[uniformNdx])
1277 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unknown uniform name: " << uniformName << TestLog::EndMessage;
1278 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1279 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name");
1283 // and with too small buffer
1285 glGetActiveUniform(program, ndx, 1, &written, &size, &type, buffer);
1289 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected 0 got " << written << TestLog::EndMessage;
1290 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1291 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got wrong uniform name length");
1296 glDeleteShader(shaderVert);
1297 glDeleteShader(shaderFrag);
1298 glDeleteProgram(program);
1299 expectError(GL_NO_ERROR);
1303 class ProgramUniformCase : public ApiCase
1306 ProgramUniformCase (Context& context, const char* name, const char* description)
1307 : ApiCase(context, name, description)
1313 const struct UniformType
1315 const char* declaration;
1316 const char* postDeclaration;
1317 const char* precision;
1325 { "float", "", "highp", "", "uniformValue", GL_FLOAT, 1, GL_FALSE },
1326 { "float", "[2]", "highp", "", "uniformValue[1]", GL_FLOAT, 2, GL_FALSE },
1327 { "vec2", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC2, 1, GL_FALSE },
1328 { "vec3", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC3, 1, GL_FALSE },
1329 { "vec4", "", "highp", "", "uniformValue.x", GL_FLOAT_VEC4, 1, GL_FALSE },
1330 { "int", "", "highp", "", "float(uniformValue)", GL_INT, 1, GL_FALSE },
1331 { "ivec2", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC2, 1, GL_FALSE },
1332 { "ivec3", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC3, 1, GL_FALSE },
1333 { "ivec4", "", "highp", "", "float(uniformValue.x)", GL_INT_VEC4, 1, GL_FALSE },
1334 { "bool", "", "", "", "float(uniformValue)", GL_BOOL, 1, GL_FALSE },
1335 { "bvec2", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC2, 1, GL_FALSE },
1336 { "bvec3", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC3, 1, GL_FALSE },
1337 { "bvec4", "", "", "", "float(uniformValue.x)", GL_BOOL_VEC4, 1, GL_FALSE },
1338 { "mat2", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT2, 1, GL_FALSE },
1339 { "mat3", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT3, 1, GL_FALSE },
1340 { "mat4", "", "highp", "", "float(uniformValue[0][0])", GL_FLOAT_MAT4, 1, GL_FALSE },
1341 { "sampler2D", "", "highp", "", "float(texture2D(uniformValue, vec2(0.0, 0.0)).r)", GL_SAMPLER_2D, 1, GL_FALSE },
1342 { "samplerCube", "", "highp", "", "float(textureCube(uniformValue, vec3(0.0, 0.0, 0.0)).r)", GL_SAMPLER_CUBE, 1, GL_FALSE },
1345 static const char* vertSource =
1346 "void main (void)\n"
1348 " gl_Position = vec4(0.0);\n"
1351 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1352 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1353 GLuint program = glCreateProgram();
1355 glAttachShader(program, shaderVert);
1356 glAttachShader(program, shaderFrag);
1358 glShaderSource(shaderVert, 1, &vertSource, DE_NULL);
1359 glCompileShader(shaderVert);
1360 expectError(GL_NO_ERROR);
1362 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uniformTypes); ++ndx)
1364 tcu::ScopedLogSection(m_log, uniformTypes[ndx].declaration, std::string("Verify type of ") + uniformTypes[ndx].declaration + " variable" + uniformTypes[ndx].postDeclaration );
1366 // gen fragment shader
1368 std::ostringstream frag;
1369 frag << uniformTypes[ndx].layout << "uniform " << uniformTypes[ndx].precision << " " << uniformTypes[ndx].declaration << " uniformValue" << uniformTypes[ndx].postDeclaration << ";\n";
1370 frag << "void main (void)\n";
1372 frag << " gl_FragColor = vec4(" << uniformTypes[ndx].getter << ");\n";
1376 std::string fragmentSource = frag.str();
1377 const char* fragmentSourceCStr = fragmentSource.c_str();
1378 glShaderSource(shaderFrag, 1, &fragmentSourceCStr, DE_NULL);
1383 glCompileShader(shaderFrag);
1384 glLinkProgram(program);
1387 if (verifyProgramParam(m_testCtx, *this, program, GL_LINK_STATUS, GL_TRUE))
1389 const GLint index = 0; // first and only active uniform
1391 char buffer[] = "not written to"; // not written to
1395 glGetActiveUniform(program, index, 0, &written, &size, &type, buffer);
1397 checkIntEquals(m_testCtx, type, uniformTypes[ndx].type);
1398 checkIntEquals(m_testCtx, size, uniformTypes[ndx].size);
1402 glDeleteShader(shaderVert);
1403 glDeleteShader(shaderFrag);
1404 glDeleteProgram(program);
1405 expectError(GL_NO_ERROR);
1409 class ActiveAttributesCase : public ApiCase
1412 ActiveAttributesCase (Context& context, const char* name, const char* description)
1413 : ApiCase(context, name, description)
1421 static const char* testVertSource =
1422 "attribute highp vec2 longInputAttributeName;\n"
1423 "attribute highp vec2 shortName;\n"
1424 "void main (void)\n"
1426 " gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n"
1428 static const char* testFragSource =
1429 "void main (void)\n"
1431 " gl_FragColor = vec4(0.0);\n"
1434 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
1435 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
1437 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
1438 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
1440 glCompileShader(shaderVert);
1441 glCompileShader(shaderFrag);
1442 expectError(GL_NO_ERROR);
1444 GLuint program = glCreateProgram();
1445 glAttachShader(program, shaderVert);
1446 glAttachShader(program, shaderFrag);
1447 glLinkProgram(program);
1448 expectError(GL_NO_ERROR);
1450 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTES, 2);
1451 verifyProgramParam(m_testCtx, *this, program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, (GLint)std::string("longInputAttributeName").length() + 1); // does include null-terminator
1454 for (int attributeNdx = 0; attributeNdx < 2; ++attributeNdx)
1456 char buffer[2048] = {'x'};
1461 glGetActiveAttrib(program, attributeNdx, DE_LENGTH_OF_ARRAY(buffer), &written, &size, &type, buffer);
1462 expectError(GL_NO_ERROR);
1464 if (deStringBeginsWith(buffer, "longInputAttributeName"))
1466 checkIntEquals(m_testCtx, written, (GLint)std::string("longInputAttributeName").length()); // does NOT include null-terminator
1468 else if (deStringBeginsWith(buffer, "shortName"))
1470 checkIntEquals(m_testCtx, written, (GLint)std::string("shortName").length()); // does NOT include null-terminator
1474 m_testCtx.getLog() << TestLog::Message << "// ERROR: Got unexpected attribute name." << TestLog::EndMessage;
1475 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
1476 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected name");
1480 // and with too short buffer
1482 char buffer[2048] = {'x'};
1488 glGetActiveAttrib(program, 0, 1, &written, &size, &type, buffer);
1489 expectError(GL_NO_ERROR);
1490 checkIntEquals(m_testCtx, written, 0);
1493 glDeleteShader(shaderVert);
1494 glDeleteShader(shaderFrag);
1495 glDeleteProgram(program);
1496 expectError(GL_NO_ERROR);
1505 GLboolean normalized;
1509 class VertexAttributeSizeCase : public ApiCase
1512 VertexAttributeSizeCase (Context& context, const char* name, const char* description)
1513 : ApiCase(context, name, description)
1519 GLfloat vertexData[4] = {0.0f}; // never accessed
1521 // test VertexAttribPointer
1522 const PointerData pointers[] =
1525 { 4, GL_FLOAT, 0, GL_FALSE, vertexData },
1526 { 3, GL_FLOAT, 0, GL_FALSE, vertexData },
1527 { 2, GL_FLOAT, 0, GL_FALSE, vertexData },
1528 { 1, GL_FLOAT, 0, GL_FALSE, vertexData },
1529 { 4, GL_SHORT, 0, GL_FALSE, vertexData },
1530 { 3, GL_SHORT, 0, GL_FALSE, vertexData },
1531 { 2, GL_SHORT, 0, GL_FALSE, vertexData },
1532 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
1535 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1537 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1538 expectError(GL_NO_ERROR);
1540 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx].size);
1545 class VertexAttributeTypeCase : public ApiCase
1548 VertexAttributeTypeCase (Context& context, const char* name, const char* description)
1549 : ApiCase(context, name, description)
1555 GLfloat vertexData[4] = {0.0f}; // never accessed
1557 const PointerData pointers[] =
1559 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
1560 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
1561 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
1562 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
1563 { 1, GL_FIXED, 0, GL_FALSE, vertexData },
1564 { 1, GL_FLOAT, 0, GL_FALSE, vertexData },
1567 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1569 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1570 expectError(GL_NO_ERROR);
1572 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx].type);
1577 class VertexAttributeStrideCase : public ApiCase
1580 VertexAttributeStrideCase (Context& context, const char* name, const char* description)
1581 : ApiCase(context, name, description)
1587 GLfloat vertexData[4] = {0.0f}; // never accessed
1589 struct StridePointerData
1597 // test VertexAttribPointer
1599 const StridePointerData pointers[] =
1601 { 1, GL_FLOAT, 0, vertexData },
1602 { 1, GL_FLOAT, 1, vertexData },
1603 { 1, GL_FLOAT, 4, vertexData },
1604 { 1, GL_SHORT, 0, vertexData },
1605 { 1, GL_SHORT, 1, vertexData },
1606 { 1, GL_SHORT, 4, vertexData },
1607 { 1, GL_FIXED, 0, vertexData },
1608 { 1, GL_FIXED, 1, vertexData },
1609 { 1, GL_FIXED, 4, vertexData },
1610 { 1, GL_BYTE, 0, vertexData },
1611 { 1, GL_UNSIGNED_SHORT, 1, vertexData },
1612 { 1, GL_UNSIGNED_SHORT, 4, vertexData },
1613 { 4, GL_UNSIGNED_BYTE, 0, vertexData },
1614 { 4, GL_UNSIGNED_BYTE, 1, vertexData },
1615 { 4, GL_UNSIGNED_BYTE, 4, vertexData },
1618 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1620 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, GL_FALSE, pointers[ndx].stride, pointers[ndx].pointer);
1621 expectError(GL_NO_ERROR);
1623 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx].stride);
1629 class VertexAttributeNormalizedCase : public ApiCase
1632 VertexAttributeNormalizedCase (Context& context, const char* name, const char* description)
1633 : ApiCase(context, name, description)
1639 GLfloat vertexData[4] = {0.0f}; // never accessed
1641 // test VertexAttribPointer
1643 const PointerData pointers[] =
1645 { 1, GL_BYTE, 0, GL_FALSE, vertexData },
1646 { 1, GL_SHORT, 0, GL_FALSE, vertexData },
1647 { 1, GL_UNSIGNED_BYTE, 0, GL_FALSE, vertexData },
1648 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, vertexData },
1649 { 1, GL_BYTE, 0, GL_TRUE, vertexData },
1650 { 1, GL_SHORT, 0, GL_TRUE, vertexData },
1651 { 1, GL_UNSIGNED_BYTE, 0, GL_TRUE, vertexData },
1652 { 1, GL_UNSIGNED_SHORT, 0, GL_TRUE, vertexData },
1655 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1657 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1658 expectError(GL_NO_ERROR);
1660 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx].normalized);
1666 class VertexAttributeEnabledCase : public ApiCase
1669 VertexAttributeEnabledCase (Context& context, const char* name, const char* description)
1670 : ApiCase(context, name, description)
1676 // VERTEX_ATTRIB_ARRAY_ENABLED
1678 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
1679 glEnableVertexAttribArray(0);
1680 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_TRUE);
1681 glDisableVertexAttribArray(0);
1682 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, GL_FALSE);
1686 class VertexAttributeBufferBindingCase : public ApiCase
1689 VertexAttributeBufferBindingCase (Context& context, const char* name, const char* description)
1690 : ApiCase(context, name, description)
1697 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 0);
1700 glGenBuffers(1, &bufferID);
1701 glBindBuffer(GL_ARRAY_BUFFER, bufferID);
1702 expectError(GL_NO_ERROR);
1704 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
1705 expectError(GL_NO_ERROR);
1707 verifyVertexAttrib(m_testCtx, *this, 0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, bufferID);
1709 glDeleteBuffers(1, &bufferID);
1710 expectError(GL_NO_ERROR);
1714 class VertexAttributePointerCase : public ApiCase
1717 VertexAttributePointerCase (Context& context, const char* name, const char* description)
1718 : ApiCase(context, name, description)
1724 StateQueryMemoryWriteGuard<GLvoid*> initialState;
1725 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &initialState);
1726 initialState.verifyValidity(m_testCtx);
1727 checkPointerEquals(m_testCtx, initialState, 0);
1729 GLfloat vertexData[4] = {0.0f}; // never accessed
1730 const PointerData pointers[] =
1732 { 1, GL_BYTE, 0, GL_FALSE, &vertexData[2] },
1733 { 1, GL_SHORT, 0, GL_FALSE, &vertexData[1] },
1734 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[2] },
1735 { 1, GL_FIXED, 0, GL_FALSE, &vertexData[1] },
1736 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[0] },
1737 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[3] },
1738 { 1, GL_FLOAT, 0, GL_FALSE, &vertexData[2] },
1739 { 1, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[0] },
1740 { 4, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[1] },
1741 { 4, GL_UNSIGNED_SHORT, 0, GL_FALSE, &vertexData[2] },
1744 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pointers); ++ndx)
1746 glVertexAttribPointer(0, pointers[ndx].size, pointers[ndx].type, pointers[ndx].normalized, pointers[ndx].stride, pointers[ndx].pointer);
1747 expectError(GL_NO_ERROR);
1749 StateQueryMemoryWriteGuard<GLvoid*> state;
1750 glGetVertexAttribPointerv(0, GL_VERTEX_ATTRIB_ARRAY_POINTER, &state);
1751 state.verifyValidity(m_testCtx);
1752 checkPointerEquals(m_testCtx, state, pointers[ndx].pointer);
1757 class UniformValueFloatCase : public ApiCase
1760 UniformValueFloatCase (Context& context, const char* name, const char* description)
1761 : ApiCase(context, name, description)
1767 static const char* testVertSource =
1768 "uniform highp float floatUniform;\n"
1769 "uniform highp vec2 float2Uniform;\n"
1770 "uniform highp vec3 float3Uniform;\n"
1771 "uniform highp vec4 float4Uniform;\n"
1772 "void main (void)\n"
1774 " gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n"
1776 static const char* testFragSource =
1778 "void main (void)\n"
1780 " gl_FragColor = vec4(0.0);\n"
1783 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1784 if (!program.isOk())
1787 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1791 glUseProgram(program.getProgram());
1792 expectError(GL_NO_ERROR);
1796 location = glGetUniformLocation(program.getProgram(), "floatUniform");
1797 glUniform1f(location, 1.0f);
1798 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), location, 1.0f);
1800 location = glGetUniformLocation(program.getProgram(), "float2Uniform");
1801 glUniform2f(location, 1.0f, 2.0f);
1802 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f);
1804 location = glGetUniformLocation(program.getProgram(), "float3Uniform");
1805 glUniform3f(location, 1.0f, 2.0f, 3.0f);
1806 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f);
1808 location = glGetUniformLocation(program.getProgram(), "float4Uniform");
1809 glUniform4f(location, 1.0f, 2.0f, 3.0f, 4.0f);
1810 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), location, 1.0f, 2.0f, 3.0f, 4.0f);
1813 expectError(GL_NO_ERROR);
1817 class UniformValueIntCase : public ApiCase
1820 UniformValueIntCase (Context& context, const char* name, const char* description)
1821 : ApiCase(context, name, description)
1827 static const char* testVertSource =
1828 "uniform highp int intUniform;\n"
1829 "uniform highp ivec2 int2Uniform;\n"
1830 "uniform highp ivec3 int3Uniform;\n"
1831 "uniform highp ivec4 int4Uniform;\n"
1832 "void main (void)\n"
1834 " gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n"
1836 static const char* testFragSource =
1837 "void main (void)\n"
1839 " gl_FragColor = vec4(0.0);\n"
1842 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1843 if (!program.isOk())
1846 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1850 glUseProgram(program.getProgram());
1851 expectError(GL_NO_ERROR);
1855 location = glGetUniformLocation(program.getProgram(), "intUniform");
1856 glUniform1i(location, 1);
1857 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1859 location = glGetUniformLocation(program.getProgram(), "int2Uniform");
1860 glUniform2i(location, 1, 2);
1861 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 2);
1863 location = glGetUniformLocation(program.getProgram(), "int3Uniform");
1864 glUniform3i(location, 1, 2, 3);
1865 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3);
1867 location = glGetUniformLocation(program.getProgram(), "int4Uniform");
1868 glUniform4i(location, 1, 2, 3, 4);
1869 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 2, 3, 4);
1872 expectError(GL_NO_ERROR);
1876 class UniformValueBooleanCase : public ApiCase
1879 UniformValueBooleanCase (Context& context, const char* name, const char* description)
1880 : ApiCase(context, name, description)
1886 static const char* testVertSource =
1887 "uniform bool boolUniform;\n"
1888 "uniform bvec2 bool2Uniform;\n"
1889 "uniform bvec3 bool3Uniform;\n"
1890 "uniform bvec4 bool4Uniform;\n"
1891 "void main (void)\n"
1893 " gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n"
1895 static const char* testFragSource =
1896 "void main (void)\n"
1898 " gl_FragColor = vec4(0.0);\n"
1901 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1902 if (!program.isOk())
1905 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1909 glUseProgram(program.getProgram());
1910 expectError(GL_NO_ERROR);
1916 location = glGetUniformLocation(program.getProgram(), "boolUniform");
1917 glUniform1i(location, 1);
1918 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1920 location = glGetUniformLocation(program.getProgram(), "bool2Uniform");
1921 glUniform2i(location, 1, 2);
1922 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1);
1924 location = glGetUniformLocation(program.getProgram(), "bool3Uniform");
1925 glUniform3i(location, 0, 1, 2);
1926 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1);
1928 location = glGetUniformLocation(program.getProgram(), "bool4Uniform");
1929 glUniform4i(location, 1, 0, 1, -1);
1930 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1);
1934 location = glGetUniformLocation(program.getProgram(), "boolUniform");
1935 glUniform1f(location, 1.0f);
1936 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1938 location = glGetUniformLocation(program.getProgram(), "bool2Uniform");
1939 glUniform2f(location, 1.0f, 0.1f);
1940 verifyUniformValue2i(m_testCtx, *this, program.getProgram(), location, 1, 1);
1942 location = glGetUniformLocation(program.getProgram(), "bool3Uniform");
1943 glUniform3f(location, 0.0f, 0.1f, -0.1f);
1944 verifyUniformValue3i(m_testCtx, *this, program.getProgram(), location, 0, 1, 1);
1946 location = glGetUniformLocation(program.getProgram(), "bool4Uniform");
1947 glUniform4f(location, 1.0f, 0.0f, 0.1f, -0.9f);
1948 verifyUniformValue4i(m_testCtx, *this, program.getProgram(), location, 1, 0, 1, 1);
1951 expectError(GL_NO_ERROR);
1955 class UniformValueSamplerCase : public ApiCase
1958 UniformValueSamplerCase (Context& context, const char* name, const char* description)
1959 : ApiCase(context, name, description)
1965 static const char* testVertSource =
1966 "void main (void)\n"
1968 " gl_Position = vec4(0.0);\n"
1970 static const char* testFragSource =
1971 "uniform highp sampler2D uniformSampler;\n"
1973 "void main (void)\n"
1975 " gl_FragColor = vec4(texture2D(uniformSampler, vec2(0.0, 0.0)).x);\n"
1978 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
1979 if (!program.isOk())
1982 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
1986 glUseProgram(program.getProgram());
1987 expectError(GL_NO_ERROR);
1991 location = glGetUniformLocation(program.getProgram(), "uniformSampler");
1992 glUniform1i(location, 1);
1993 verifyUniformValue1i(m_testCtx, *this, program.getProgram(), location, 1);
1996 expectError(GL_NO_ERROR);
2000 class UniformValueArrayCase : public ApiCase
2003 UniformValueArrayCase (Context& context, const char* name, const char* description)
2004 : ApiCase(context, name, description)
2010 static const char* testVertSource =
2011 "uniform highp float arrayUniform[5];"
2012 "uniform highp vec2 array2Uniform[5];"
2013 "uniform highp vec3 array3Uniform[5];"
2014 "uniform highp vec4 array4Uniform[5];"
2015 "void main (void)\n"
2018 " + vec4(arrayUniform[0] + arrayUniform[1] + arrayUniform[2] + arrayUniform[3] + arrayUniform[4])\n"
2019 " + vec4(array2Uniform[0].x + array2Uniform[1].x + array2Uniform[2].x + array2Uniform[3].x + array2Uniform[4].x)\n"
2020 " + vec4(array3Uniform[0].x + array3Uniform[1].x + array3Uniform[2].x + array3Uniform[3].x + array3Uniform[4].x)\n"
2021 " + vec4(array4Uniform[0].x + array4Uniform[1].x + array4Uniform[2].x + array4Uniform[3].x + array4Uniform[4].x);\n"
2023 static const char* testFragSource =
2025 "void main (void)\n"
2027 " gl_FragColor = vec4(0.0);\n"
2030 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
2031 if (!program.isOk())
2034 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
2038 glUseProgram(program.getProgram());
2039 expectError(GL_NO_ERROR);
2043 float uniformValue[5 * 4] =
2045 -1.0f, 0.1f, 4.0f, 800.0f,
2046 13.0f, 55.0f, 12.0f, 91.0f,
2047 -55.1f, 1.1f, 98.0f, 19.0f,
2048 41.0f, 65.0f, 4.0f, 12.2f,
2049 95.0f, 77.0f, 32.0f, 48.0f
2052 location = glGetUniformLocation(program.getProgram(), "arrayUniform");
2053 glUniform1fv(location, 5, uniformValue);
2054 expectError(GL_NO_ERROR);
2056 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[0]"), uniformValue[0]);
2057 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[1]"), uniformValue[1]);
2058 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[2]"), uniformValue[2]);
2059 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[3]"), uniformValue[3]);
2060 verifyUniformValue1f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "arrayUniform[4]"), uniformValue[4]);
2061 expectError(GL_NO_ERROR);
2063 location = glGetUniformLocation(program.getProgram(),"array2Uniform");
2064 glUniform2fv(location, 5, uniformValue);
2065 expectError(GL_NO_ERROR);
2067 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[0]"), uniformValue[2 * 0], uniformValue[(2 * 0) + 1]);
2068 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[1]"), uniformValue[2 * 1], uniformValue[(2 * 1) + 1]);
2069 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[2]"), uniformValue[2 * 2], uniformValue[(2 * 2) + 1]);
2070 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[3]"), uniformValue[2 * 3], uniformValue[(2 * 3) + 1]);
2071 verifyUniformValue2f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array2Uniform[4]"), uniformValue[2 * 4], uniformValue[(2 * 4) + 1]);
2072 expectError(GL_NO_ERROR);
2074 location = glGetUniformLocation(program.getProgram(),"array3Uniform");
2075 glUniform3fv(location, 5, uniformValue);
2076 expectError(GL_NO_ERROR);
2078 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[0]"), uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]);
2079 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[1]"), uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]);
2080 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[2]"), uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]);
2081 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[3]"), uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]);
2082 verifyUniformValue3f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array3Uniform[4]"), uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]);
2083 expectError(GL_NO_ERROR);
2085 location = glGetUniformLocation(program.getProgram(),"array4Uniform");
2086 glUniform4fv(location, 5, uniformValue);
2087 expectError(GL_NO_ERROR);
2089 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[0]"), uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]);
2090 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[1]"), uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]);
2091 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[2]"), uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]);
2092 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[3]"), uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]);
2093 verifyUniformValue4f(m_testCtx, *this, program.getProgram(), glGetUniformLocation(program.getProgram(), "array4Uniform[4]"), uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]);
2094 expectError(GL_NO_ERROR);
2097 expectError(GL_NO_ERROR);
2101 class UniformValueMatrixCase : public ApiCase
2104 UniformValueMatrixCase (Context& context, const char* name, const char* description)
2105 : ApiCase(context, name, description)
2111 static const char* testVertSource =
2112 "uniform highp mat2 mat2Uniform;"
2113 "uniform highp mat3 mat3Uniform;"
2114 "uniform highp mat4 mat4Uniform;"
2115 "void main (void)\n"
2117 " gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n"
2119 static const char* testFragSource =
2121 "void main (void)\n"
2123 " gl_FragColor = vec4(0.0);\n"
2126 glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(testVertSource, testFragSource));
2127 if (!program.isOk())
2130 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to compile shader");
2134 glUseProgram(program.getProgram());
2135 expectError(GL_NO_ERROR);
2139 float matrixValues[4 * 4] =
2141 -1.0f, 0.1f, 4.0f, 800.0f,
2142 13.0f, 55.0f, 12.0f, 91.0f,
2143 -55.1f, 1.1f, 98.0f, 19.0f,
2144 41.0f, 65.0f, 4.0f, 12.2f,
2147 // the values of the matrix are returned in column major order but they can be given in either order
2149 location = glGetUniformLocation(program.getProgram(), "mat2Uniform");
2150 glUniformMatrix2fv(location, 1, GL_FALSE, matrixValues);
2151 verifyUniformMatrixValues<2>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);
2153 location = glGetUniformLocation(program.getProgram(), "mat3Uniform");
2154 glUniformMatrix3fv(location, 1, GL_FALSE, matrixValues);
2155 verifyUniformMatrixValues<3>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);
2157 location = glGetUniformLocation(program.getProgram(), "mat4Uniform");
2158 glUniformMatrix4fv(location, 1, GL_FALSE, matrixValues);
2159 verifyUniformMatrixValues<4>(m_testCtx, *this, program.getProgram(), location, matrixValues, false);
2162 expectError(GL_NO_ERROR);
2166 class PrecisionFormatCase : public ApiCase
2169 struct RequiredFormat
2176 PrecisionFormatCase (Context& context, const char* name, const char* description, glw::GLenum shaderType, glw::GLenum precisionType)
2177 : ApiCase (context, name, description)
2178 , m_shaderType (shaderType)
2179 , m_precisionType (precisionType)
2186 const RequiredFormat expected = getRequiredFormat();
2188 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLboolean> shaderCompiler;
2189 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint[2]> range;
2190 gls::StateQueryUtil::StateQueryMemoryWriteGuard<glw::GLint> precision;
2192 // requires SHADER_COMPILER = true
2193 glGetBooleanv(GL_SHADER_COMPILER, &shaderCompiler);
2194 expectError(GL_NO_ERROR);
2196 if (!shaderCompiler.verifyValidity(m_testCtx))
2198 if (shaderCompiler != GL_TRUE)
2199 throw tcu::NotSupportedError("SHADER_COMPILER = TRUE required");
2202 glGetShaderPrecisionFormat(m_shaderType, m_precisionType, range, &precision);
2203 expectError(GL_NO_ERROR);
2205 if (!range.verifyValidity(m_testCtx))
2207 if (!precision.verifyValidity(m_testCtx))
2211 << tcu::TestLog::Message
2212 << "range[0] = " << range[0] << "\n"
2213 << "range[1] = " << range[1] << "\n"
2214 << "precision = " << precision
2215 << tcu::TestLog::EndMessage;
2217 // special case for highp and fragment shader
2219 if (m_shaderType == GL_FRAGMENT_SHADER && (m_precisionType == GL_HIGH_FLOAT || m_precisionType == GL_HIGH_INT))
2221 // not supported is a valid return value
2222 if (range[0] == 0 && range[1] == 0 && precision == 0)
2226 // verify the returned values
2228 if (range[0] < expected.negativeRange)
2230 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[0], expected greater or equal to " << expected.negativeRange << tcu::TestLog::EndMessage;
2234 if (range[1] < expected.positiveRange)
2236 m_log << tcu::TestLog::Message << "// ERROR: Invalid range[1], expected greater or equal to " << expected.positiveRange << tcu::TestLog::EndMessage;
2240 if (precision < expected.precision)
2242 m_log << tcu::TestLog::Message << "// ERROR: Invalid precision, expected greater or equal to " << expected.precision << tcu::TestLog::EndMessage;
2247 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid precision/range");
2250 RequiredFormat getRequiredFormat (void) const
2252 // Precisions for different types.
2253 // For example highp float: range: (-2^62, 2^62) => min = -2^62 + e, max = 2^62 - e
2254 const RequiredFormat requirements[] =
2256 { 0, 0, 8 }, //!< lowp float
2257 { 13, 13, 10 }, //!< mediump float
2258 { 61, 61, 16 }, //!< highp float
2259 { 7, 7, 0 }, //!< lowp int
2260 { 9, 9, 0 }, //!< mediump int
2261 { 15, 15, 0 }, //!< highp int
2263 const int ndx = (int)m_precisionType - (int)GL_LOW_FLOAT;
2265 DE_ASSERT(ndx >= 0);
2266 DE_ASSERT(ndx < DE_LENGTH_OF_ARRAY(requirements));
2267 return requirements[ndx];
2270 const glw::GLenum m_shaderType;
2271 const glw::GLenum m_precisionType;
2277 ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
2278 : TestCaseGroup(context, "shader", "Shader State Query tests")
2282 void ShaderStateQueryTests::init (void)
2285 addChild(new ShaderTypeCase (m_context, "shader_type", "SHADER_TYPE"));
2286 addChild(new ShaderCompileStatusCase (m_context, "shader_compile_status", "COMPILE_STATUS"));
2287 addChild(new ShaderInfoLogCase (m_context, "shader_info_log_length", "INFO_LOG_LENGTH"));
2288 addChild(new ShaderSourceCase (m_context, "shader_source_length", "SHADER_SOURCE_LENGTH"));
2290 // shader and program
2291 addChild(new DeleteStatusCase (m_context, "delete_status", "DELETE_STATUS"));
2294 addChild(new CurrentVertexAttribInitialCase (m_context, "current_vertex_attrib_initial", "CURRENT_VERTEX_ATTRIB"));
2295 addChild(new CurrentVertexAttribFloatCase (m_context, "current_vertex_attrib_float", "CURRENT_VERTEX_ATTRIB"));
2296 addChild(new CurrentVertexAttribConversionCase (m_context, "current_vertex_attrib_float_to_int", "CURRENT_VERTEX_ATTRIB"));
2299 addChild(new ProgramInfoLogCase (m_context, "program_info_log_length", "INFO_LOG_LENGTH"));
2300 addChild(new ProgramValidateStatusCase (m_context, "program_validate_status", "VALIDATE_STATUS"));
2301 addChild(new ProgramAttachedShadersCase (m_context, "program_attached_shaders", "ATTACHED_SHADERS"));
2303 addChild(new ProgramActiveUniformNameCase (m_context, "program_active_uniform_name", "ACTIVE_UNIFORMS and ACTIVE_UNIFORM_MAX_LENGTH"));
2304 addChild(new ProgramUniformCase (m_context, "program_active_uniform_types", "UNIFORM_TYPE and UNIFORM_SIZE"));
2306 // attribute related
2307 addChild(new ActiveAttributesCase (m_context, "active_attributes", "ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH"));
2308 addChild(new VertexAttributeSizeCase (m_context, "vertex_attrib_size", "VERTEX_ATTRIB_ARRAY_SIZE"));
2309 addChild(new VertexAttributeTypeCase (m_context, "vertex_attrib_type", "VERTEX_ATTRIB_ARRAY_TYPE"));
2310 addChild(new VertexAttributeStrideCase (m_context, "vertex_attrib_stride", "VERTEX_ATTRIB_ARRAY_STRIDE"));
2311 addChild(new VertexAttributeNormalizedCase (m_context, "vertex_attrib_normalized", "VERTEX_ATTRIB_ARRAY_NORMALIZED"));
2312 addChild(new VertexAttributeEnabledCase (m_context, "vertex_attrib_array_enabled", "VERTEX_ATTRIB_ARRAY_ENABLED"));
2313 addChild(new VertexAttributeBufferBindingCase (m_context, "vertex_attrib_array_buffer_binding", "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"));
2314 addChild(new VertexAttributePointerCase (m_context, "vertex_attrib_pointerv", "GetVertexAttribPointerv"));
2317 addChild(new UniformValueFloatCase (m_context, "uniform_value_float", "GetUniform*"));
2318 addChild(new UniformValueIntCase (m_context, "uniform_value_int", "GetUniform*"));
2319 addChild(new UniformValueBooleanCase (m_context, "uniform_value_boolean", "GetUniform*"));
2320 addChild(new UniformValueSamplerCase (m_context, "uniform_value_sampler", "GetUniform*"));
2321 addChild(new UniformValueArrayCase (m_context, "uniform_value_array", "GetUniform*"));
2322 addChild(new UniformValueMatrixCase (m_context, "uniform_value_matrix", "GetUniform*"));
2324 // precision format query
2325 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_FLOAT));
2326 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_FLOAT));
2327 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_float", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_FLOAT));
2328 addChild(new PrecisionFormatCase (m_context, "precision_vertex_lowp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_LOW_INT));
2329 addChild(new PrecisionFormatCase (m_context, "precision_vertex_mediump_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_MEDIUM_INT));
2330 addChild(new PrecisionFormatCase (m_context, "precision_vertex_highp_int", "GetShaderPrecisionFormat", GL_VERTEX_SHADER, GL_HIGH_INT));
2331 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_FLOAT));
2332 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT));
2333 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_float", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_FLOAT));
2334 addChild(new PrecisionFormatCase (m_context, "precision_fragment_lowp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_LOW_INT));
2335 addChild(new PrecisionFormatCase (m_context, "precision_fragment_mediump_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_MEDIUM_INT));
2336 addChild(new PrecisionFormatCase (m_context, "precision_fragment_highp_int", "GetShaderPrecisionFormat", GL_FRAGMENT_SHADER, GL_HIGH_INT));