/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 3.0 Module * ------------------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Indexed State Query tests. *//*--------------------------------------------------------------------*/ #include "es3fIndexedStateQueryTests.hpp" #include "es3fApiCase.hpp" #include "glsStateQueryUtil.hpp" #include "tcuRenderTarget.hpp" #include "tcuTestLog.hpp" #include "glwEnums.hpp" #include "gluRenderContext.hpp" #include "gluCallLogWrapper.hpp" #include "gluContextInfo.hpp" #include "deRandom.hpp" namespace deqp { namespace gles3 { namespace Functional { namespace { using namespace glw; // GLint and other GL types using namespace gls::StateQueryUtil; void checkIntEquals(tcu::TestContext &testCtx, GLint got, GLint expected) { using tcu::TestLog; if (got != expected) { testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); } } void checkIntEquals(tcu::TestContext &testCtx, GLint64 got, GLint64 expected) { using tcu::TestLog; if (got != expected) { testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage; if (testCtx.getTestResult() == QP_TEST_RESULT_PASS) testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); } } class TransformFeedbackCase : public ApiCase { public: TransformFeedbackCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description) { } virtual void testTransformFeedback(void) = DE_NULL; void test(void) { static const char *transformFeedbackTestVertSource = "#version 300 es\n" "out highp vec4 anotherOutput;\n" "void main (void)\n" "{\n" " gl_Position = vec4(0.0);\n" " anotherOutput = vec4(0.0);\n" "}\n\0"; static const char *transformFeedbackTestFragSource = "#version 300 es\n" "layout(location = 0) out mediump vec4 fragColor;" "void main (void)\n" "{\n" " fragColor = vec4(0.0);\n" "}\n\0"; GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL); glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL); glCompileShader(shaderVert); glCompileShader(shaderFrag); expectError(GL_NO_ERROR); GLuint shaderProg = glCreateProgram(); glAttachShader(shaderProg, shaderVert); glAttachShader(shaderProg, shaderFrag); const char *transformFeedbackOutputs[] = {"gl_Position", "anotherOutput"}; glTransformFeedbackVaryings(shaderProg, 2, transformFeedbackOutputs, GL_INTERLEAVED_ATTRIBS); glLinkProgram(shaderProg); expectError(GL_NO_ERROR); glGenTransformFeedbacks(2, transformFeedbacks); // Also store the default transform feedback in the array. transformFeedbacks[2] = 0; glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[0]); expectError(GL_NO_ERROR); testTransformFeedback(); // cleanup glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); glDeleteTransformFeedbacks(2, transformFeedbacks); glDeleteShader(shaderVert); glDeleteShader(shaderFrag); glDeleteProgram(shaderProg); expectError(GL_NO_ERROR); } protected: GLuint transformFeedbacks[3]; }; class TransformFeedbackBufferBindingCase : public TransformFeedbackCase { public: TransformFeedbackBufferBindingCase(Context &context, const char *name, const char *description) : TransformFeedbackCase(context, name, description) { } void testTransformFeedback(void) { const int feedbackPositionIndex = 0; const int feedbackOutputIndex = 1; const int feedbackIndex[2] = {feedbackPositionIndex, feedbackOutputIndex}; // bind bffers GLuint feedbackBuffers[2]; glGenBuffers(2, feedbackBuffers); expectError(GL_NO_ERROR); for (int ndx = 0; ndx < 2; ++ndx) { glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[ndx]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackIndex[ndx], feedbackBuffers[ndx]); expectError(GL_NO_ERROR); } // test TRANSFORM_FEEDBACK_BUFFER_BINDING for (int ndx = 0; ndx < 2; ++ndx) { StateQueryMemoryWriteGuard boundBuffer; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, feedbackIndex[ndx], &boundBuffer); boundBuffer.verifyValidity(m_testCtx); checkIntEquals(m_testCtx, boundBuffer, feedbackBuffers[ndx]); } // cleanup glDeleteBuffers(2, feedbackBuffers); } }; class TransformFeedbackBufferBufferCase : public TransformFeedbackCase { public: TransformFeedbackBufferBufferCase(Context &context, const char *name, const char *description) : TransformFeedbackCase(context, name, description) { } void testTransformFeedback(void) { const int feedbackPositionIndex = 0; const int feedbackOutputIndex = 1; const int rangeBufferOffset = 4; const int rangeBufferSize = 8; // bind buffers GLuint feedbackBuffers[2]; glGenBuffers(2, feedbackBuffers); expectError(GL_NO_ERROR); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[0]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackPositionIndex, feedbackBuffers[0]); expectError(GL_NO_ERROR); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[1]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ); glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackOutputIndex, feedbackBuffers[1], rangeBufferOffset, rangeBufferSize); expectError(GL_NO_ERROR); // test TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE const struct BufferRequirements { GLint index; GLenum pname; GLint64 value; } requirements[] = {{feedbackPositionIndex, GL_TRANSFORM_FEEDBACK_BUFFER_START, 0}, {feedbackPositionIndex, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, 0}, {feedbackOutputIndex, GL_TRANSFORM_FEEDBACK_BUFFER_START, rangeBufferOffset}, {feedbackOutputIndex, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, rangeBufferSize}}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requirements); ++ndx) { StateQueryMemoryWriteGuard state; glGetInteger64i_v(requirements[ndx].pname, requirements[ndx].index, &state); if (state.verifyValidity(m_testCtx)) checkIntEquals(m_testCtx, state, requirements[ndx].value); } // cleanup glDeleteBuffers(2, feedbackBuffers); } }; class TransformFeedbackSwitchingBufferCase : public TransformFeedbackCase { public: TransformFeedbackSwitchingBufferCase(Context &context, const char *name, const char *description) : TransformFeedbackCase(context, name, description) { } void testTransformFeedback(void) { GLuint feedbackBuffers[3]; glGenBuffers(3, feedbackBuffers); expectError(GL_NO_ERROR); for (int i = 0; i < 3; ++i) { glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]); expectError(GL_NO_ERROR); GLint value; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value); expectError(GL_NO_ERROR); checkIntEquals(m_testCtx, value, 0); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, feedbackBuffers[i]); expectError(GL_NO_ERROR); // glBindBufferBase should also set the generic binding point. glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value); expectError(GL_NO_ERROR); checkIntEquals(m_testCtx, value, feedbackBuffers[i]); } for (int i = 0; i < 3; ++i) { // glBindTransformFeedback should change the indexed binding points, but // not the generic one. glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]); expectError(GL_NO_ERROR); GLint value; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value); expectError(GL_NO_ERROR); checkIntEquals(m_testCtx, value, feedbackBuffers[i]); glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value); expectError(GL_NO_ERROR); // Should be unchanged. checkIntEquals(m_testCtx, value, feedbackBuffers[2]); } glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[0]); expectError(GL_NO_ERROR); glDeleteBuffers(3, feedbackBuffers); expectError(GL_NO_ERROR); // After deleting buffers the bound state should be changed but unbound // state should be unchanged. GLint value; glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value); expectError(GL_NO_ERROR); checkIntEquals(m_testCtx, value, 0); glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value); expectError(GL_NO_ERROR); checkIntEquals(m_testCtx, value, 0); for (int i = 1; i < 3; ++i) { glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]); expectError(GL_NO_ERROR); glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value); expectError(GL_NO_ERROR); checkIntEquals(m_testCtx, value, feedbackBuffers[i]); glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value); expectError(GL_NO_ERROR); checkIntEquals(m_testCtx, value, 0); } } }; class UniformBufferCase : public ApiCase { public: UniformBufferCase(Context &context, const char *name, const char *description) : ApiCase(context, name, description) , m_program(0) { } virtual void testUniformBuffers(void) = DE_NULL; void test(void) { static const char *testVertSource = "#version 300 es\n" "uniform highp vec4 input1;\n" "uniform highp vec4 input2;\n" "void main (void)\n" "{\n" " gl_Position = input1 + input2;\n" "}\n\0"; static const char *testFragSource = "#version 300 es\n" "layout(location = 0) out mediump vec4 fragColor;" "void main (void)\n" "{\n" " fragColor = vec4(0.0);\n" "}\n\0"; GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER); GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(shaderVert, 1, &testVertSource, DE_NULL); glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL); glCompileShader(shaderVert); glCompileShader(shaderFrag); expectError(GL_NO_ERROR); m_program = glCreateProgram(); glAttachShader(m_program, shaderVert); glAttachShader(m_program, shaderFrag); glLinkProgram(m_program); glUseProgram(m_program); expectError(GL_NO_ERROR); testUniformBuffers(); glUseProgram(0); glDeleteShader(shaderVert); glDeleteShader(shaderFrag); glDeleteProgram(m_program); expectError(GL_NO_ERROR); } protected: GLuint m_program; }; class UniformBufferBindingCase : public UniformBufferCase { public: UniformBufferBindingCase(Context &context, const char *name, const char *description) : UniformBufferCase(context, name, description) { } void testUniformBuffers(void) { const char *uniformNames[] = {"input1", "input2"}; GLuint uniformIndices[2] = {0}; glGetUniformIndices(m_program, 2, uniformNames, uniformIndices); GLuint buffers[2]; glGenBuffers(2, buffers); for (int ndx = 0; ndx < 2; ++ndx) { glBindBuffer(GL_UNIFORM_BUFFER, buffers[ndx]); glBufferData(GL_UNIFORM_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, uniformIndices[ndx], buffers[ndx]); expectError(GL_NO_ERROR); } for (int ndx = 0; ndx < 2; ++ndx) { StateQueryMemoryWriteGuard boundBuffer; glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, uniformIndices[ndx], &boundBuffer); if (boundBuffer.verifyValidity(m_testCtx)) checkIntEquals(m_testCtx, boundBuffer, buffers[ndx]); expectError(GL_NO_ERROR); } glDeleteBuffers(2, buffers); } }; class UniformBufferBufferCase : public UniformBufferCase { public: UniformBufferBufferCase(Context &context, const char *name, const char *description) : UniformBufferCase(context, name, description) { } void testUniformBuffers(void) { const char *uniformNames[] = {"input1", "input2"}; GLuint uniformIndices[2] = {0}; glGetUniformIndices(m_program, 2, uniformNames, uniformIndices); const GLint alignment = GetAlignment(); if (alignment == -1) // cannot continue without this return; m_testCtx.getLog() << tcu::TestLog::Message << "Alignment is " << alignment << tcu::TestLog::EndMessage; int rangeBufferOffset = alignment; int rangeBufferSize = alignment * 2; int rangeBufferTotalSize = rangeBufferOffset + rangeBufferSize + 8; // + 8 has no special meaning, just to make it != with the size of the range GLuint buffers[2]; glGenBuffers(2, buffers); glBindBuffer(GL_UNIFORM_BUFFER, buffers[0]); glBufferData(GL_UNIFORM_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, uniformIndices[0], buffers[0]); expectError(GL_NO_ERROR); glBindBuffer(GL_UNIFORM_BUFFER, buffers[1]); glBufferData(GL_UNIFORM_BUFFER, rangeBufferTotalSize, DE_NULL, GL_DYNAMIC_DRAW); glBindBufferRange(GL_UNIFORM_BUFFER, uniformIndices[1], buffers[1], rangeBufferOffset, rangeBufferSize); expectError(GL_NO_ERROR); // test UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE const struct BufferRequirements { GLuint index; GLenum pname; GLint64 value; } requirements[] = {{uniformIndices[0], GL_UNIFORM_BUFFER_START, 0}, {uniformIndices[0], GL_UNIFORM_BUFFER_SIZE, 0}, {uniformIndices[1], GL_UNIFORM_BUFFER_START, rangeBufferOffset}, {uniformIndices[1], GL_UNIFORM_BUFFER_SIZE, rangeBufferSize}}; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requirements); ++ndx) { StateQueryMemoryWriteGuard state; glGetInteger64i_v(requirements[ndx].pname, requirements[ndx].index, &state); if (state.verifyValidity(m_testCtx)) checkIntEquals(m_testCtx, state, requirements[ndx].value); expectError(GL_NO_ERROR); } glDeleteBuffers(2, buffers); } int GetAlignment() { StateQueryMemoryWriteGuard state; glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &state); if (!state.verifyValidity(m_testCtx)) return -1; if (state <= 256) return state; m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: UNIFORM_BUFFER_OFFSET_ALIGNMENT has a maximum value of 256." << tcu::TestLog::EndMessage; m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid UNIFORM_BUFFER_OFFSET_ALIGNMENT value"); return -1; } }; const char *getVerifierSuffix(QueryType type) { switch (type) { case QUERY_INDEXED_INTEGER: return "getintegeri_v"; case QUERY_INDEXED_INTEGER64: return "getinteger64i_v"; case QUERY_INDEXED_INTEGER_VEC4: return "getintegeri_v"; case QUERY_INDEXED_INTEGER64_VEC4: return "getinteger64i_v"; case QUERY_INDEXED_ISENABLED: return "isenabledi"; default: DE_ASSERT(false); return DE_NULL; } } void isExtensionSupported(Context &context, std::string extensionName) { if (contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5))) return; if (extensionName == "GL_EXT_draw_buffers_indexed" || extensionName == "GL_KHR_blend_equation_advanced") { if (!contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !context.getContextInfo().isExtensionSupported(extensionName.c_str())) TCU_THROW(NotSupportedError, (std::string("Extension ") + extensionName + std::string(" not supported.")).c_str()); } else if (!context.getContextInfo().isExtensionSupported(extensionName.c_str())) TCU_THROW(NotSupportedError, (std::string("Extension ") + extensionName + std::string(" not supported.")).c_str()); } class EnableBlendCase : public TestCase { public: EnableBlendCase(Context &context, const char *name, const char *desc, QueryType verifierType); void init(void); private: IterateResult iterate(void); const QueryType m_verifierType; }; EnableBlendCase::EnableBlendCase(Context &context, const char *name, const char *desc, QueryType verifierType) : TestCase(context, name, desc) , m_verifierType(verifierType) { } void EnableBlendCase::init(void) { isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed"); } EnableBlendCase::IterateResult EnableBlendCase::iterate(void) { glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: "); int32_t maxDrawBuffers = 0; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, false, m_verifierType); } { const tcu::ScopedLogSection superSection(m_testCtx.getLog(), "AfterSettingCommon", "After setting common"); gl.glEnable(GL_BLEND); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, true, m_verifierType); } { const tcu::ScopedLogSection superSection(m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) { if (ndx % 2 == 0) gl.glEnablei(GL_BLEND, ndx); else gl.glDisablei(GL_BLEND, ndx); } for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, (ndx % 2 == 0), m_verifierType); } { const tcu::ScopedLogSection superSection(m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) { if (ndx % 2 == 0) gl.glEnablei(GL_BLEND, ndx); else gl.glDisablei(GL_BLEND, ndx); } gl.glEnable(GL_BLEND); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, true, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class ColorMaskCase : public TestCase { public: ColorMaskCase(Context &context, const char *name, const char *desc, QueryType verifierType); void init(void); private: IterateResult iterate(void); const QueryType m_verifierType; }; ColorMaskCase::ColorMaskCase(Context &context, const char *name, const char *desc, QueryType verifierType) : TestCase(context, name, desc) , m_verifierType(verifierType) { } void ColorMaskCase::init(void) { isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed"); } ColorMaskCase::IterateResult ColorMaskCase::iterate(void) { glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: "); int32_t maxDrawBuffers = 0; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBooleanVec4(result, gl, GL_COLOR_WRITEMASK, ndx, tcu::BVec4(true), m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingCommon", "After setting common"); gl.glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBooleanVec4(result, gl, GL_COLOR_WRITEMASK, ndx, tcu::BVec4(false, true, true, false), m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glColorMaski(ndx, (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE), (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE)); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBooleanVec4( result, gl, GL_COLOR_WRITEMASK, ndx, (ndx % 2 == 0 ? tcu::BVec4(true, false, true, false) : tcu::BVec4(false, true, false, true)), m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glColorMaski(ndx, (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE), (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE)); gl.glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedBooleanVec4(result, gl, GL_COLOR_WRITEMASK, ndx, tcu::BVec4(false, true, true, false), m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class BlendFuncCase : public TestCase { public: BlendFuncCase(Context &context, const char *name, const char *desc, QueryType verifierType); void init(void); private: IterateResult iterate(void); const QueryType m_verifierType; }; BlendFuncCase::BlendFuncCase(Context &context, const char *name, const char *desc, QueryType verifierType) : TestCase(context, name, desc) , m_verifierType(verifierType) { } void BlendFuncCase::init(void) { isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed"); } BlendFuncCase::IterateResult BlendFuncCase::iterate(void) { const uint32_t blendFuncs[] = {GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE}; glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: "); int32_t maxDrawBuffers = 0; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_ONE, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_ZERO, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_ONE, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_ZERO, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingCommon", "After setting common"); gl.glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_DST_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_SRC_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_DST_ALPHA, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingCommonSeparate", "After setting common separate"); gl.glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_COLOR, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_ONE_MINUS_SRC_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_DST_COLOR, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_ONE_MINUS_DST_ALPHA, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendFunci(ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)]); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingIndexedSeparate", "After setting indexed separate"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendFuncSeparatei(ndx, blendFuncs[(ndx + 3) % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 2) % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 0) % DE_LENGTH_OF_ARRAY(blendFuncs)]); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, blendFuncs[(ndx + 3) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, blendFuncs[(ndx + 2) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, blendFuncs[(ndx + 0) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendFunci(ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)]); gl.glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_DST_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_SRC_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_DST_ALPHA, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterResettingIndexedWithCommonSeparate", "After resetting indexed with common separate"); gl.glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendFuncSeparatei(ndx, blendFuncs[(ndx + 3) % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 2) % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 0) % DE_LENGTH_OF_ARRAY(blendFuncs)]); gl.glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_COLOR, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_ONE_MINUS_SRC_ALPHA, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_DST_COLOR, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_ONE_MINUS_DST_ALPHA, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class BlendEquationCase : public TestCase { public: BlendEquationCase(Context &context, const char *name, const char *desc, QueryType verifierType); void init(void); private: IterateResult iterate(void); const QueryType m_verifierType; }; BlendEquationCase::BlendEquationCase(Context &context, const char *name, const char *desc, QueryType verifierType) : TestCase(context, name, desc) , m_verifierType(verifierType) { } void BlendEquationCase::init(void) { isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed"); } BlendEquationCase::IterateResult BlendEquationCase::iterate(void) { const uint32_t blendEquations[] = {GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX}; glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: "); int32_t maxDrawBuffers = 0; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_ADD, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_ADD, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingCommon", "After setting common"); gl.glBlendEquation(GL_FUNC_SUBTRACT); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_SUBTRACT, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingCommonSeparate", "After setting common separate"); gl.glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_SUBTRACT); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_REVERSE_SUBTRACT, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendEquationi(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)]); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingIndexedSeparate", "After setting indexed separate"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendEquationSeparatei(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)]); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendEquationi(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)]); gl.glBlendEquation(GL_FUNC_SUBTRACT); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_SUBTRACT, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterResettingIndexedWithCommonSeparate", "After resetting indexed with common separate"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendEquationSeparatei(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)]); gl.glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_SUBTRACT); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_REVERSE_SUBTRACT, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class BlendEquationAdvancedCase : public TestCase { public: BlendEquationAdvancedCase(Context &context, const char *name, const char *desc, QueryType verifierType); void init(void); private: IterateResult iterate(void); const QueryType m_verifierType; }; BlendEquationAdvancedCase::BlendEquationAdvancedCase(Context &context, const char *name, const char *desc, QueryType verifierType) : TestCase(context, name, desc) , m_verifierType(verifierType) { } void BlendEquationAdvancedCase::init(void) { isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed"); isExtensionSupported(m_context, "GL_KHR_blend_equation_advanced"); } BlendEquationAdvancedCase::IterateResult BlendEquationAdvancedCase::iterate(void) { const uint32_t blendEquations[] = {GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX}; const uint32_t blendEquationAdvanced[] = {GL_MULTIPLY, GL_SCREEN, GL_OVERLAY, GL_DARKEN, GL_LIGHTEN, GL_COLORDODGE, GL_COLORBURN, GL_HARDLIGHT, GL_SOFTLIGHT, GL_DIFFERENCE, GL_EXCLUSION, GL_HSL_HUE, GL_HSL_SATURATION, GL_HSL_COLOR, GL_HSL_LUMINOSITY}; glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: "); int32_t maxDrawBuffers = 0; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingCommon", "After setting common"); gl.glBlendEquation(GL_SCREEN); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_SCREEN, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_SCREEN, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendEquationi(ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)]); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)], m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)], m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendEquationi(ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)]); gl.glBlendEquation(GL_MULTIPLY); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_MULTIPLY, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_MULTIPLY, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "AfterResettingIndexedSeparateWithCommon", "After resetting indexed separate with common"); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) gl.glBlendEquationSeparatei(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)]); gl.glBlendEquation(GL_LIGHTEN); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_LIGHTEN, m_verifierType); for (int ndx = 0; ndx < maxDrawBuffers; ++ndx) verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_LIGHTEN, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } } // namespace IndexedStateQueryTests::IndexedStateQueryTests(Context &context) : TestCaseGroup(context, "indexed", "Indexed Integer Values") { } void IndexedStateQueryTests::init(void) { // transform feedback addChild(new TransformFeedbackBufferBindingCase(m_context, "transform_feedback_buffer_binding", "TRANSFORM_FEEDBACK_BUFFER_BINDING")); addChild( new TransformFeedbackBufferBufferCase(m_context, "transform_feedback_buffer_start_size", "TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE")); addChild(new TransformFeedbackSwitchingBufferCase( m_context, "transform_feedback_switching_buffer", "TRANSFORM_FEEDBACK_BUFFER_BINDING while switching transform feedback objects")); // uniform buffers addChild(new UniformBufferBindingCase(m_context, "uniform_buffer_binding", "UNIFORM_BUFFER_BINDING")); addChild(new UniformBufferBufferCase(m_context, "uniform_buffer_start_size", "UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE")); static const QueryType verifiers[] = {QUERY_INDEXED_INTEGER, QUERY_INDEXED_INTEGER64}; static const QueryType vec4Verifiers[] = {QUERY_INDEXED_INTEGER_VEC4, QUERY_INDEXED_INTEGER64_VEC4}; #define FOR_EACH_VERIFIER(X) \ for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx) \ { \ const QueryType verifier = verifiers[verifierNdx]; \ const char *verifierSuffix = getVerifierSuffix(verifier); \ this->addChild(X); \ } #define FOR_EACH_VEC4_VERIFIER(X) \ for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(vec4Verifiers); ++verifierNdx) \ { \ const QueryType verifier = vec4Verifiers[verifierNdx]; \ const char *verifierSuffix = getVerifierSuffix(verifier); \ this->addChild(X); \ } addChild(new EnableBlendCase(m_context, "blend_isenabledi", "BLEND", QUERY_INDEXED_ISENABLED)); FOR_EACH_VEC4_VERIFIER(new ColorMaskCase(m_context, (std::string() + "color_mask_" + verifierSuffix).c_str(), "COLOR_WRITEMASK", verifier)) FOR_EACH_VERIFIER(new BlendFuncCase(m_context, (std::string() + "blend_func_" + verifierSuffix).c_str(), "BLEND_SRC and BLEND_DST", verifier)) FOR_EACH_VERIFIER(new BlendEquationCase(m_context, (std::string() + "blend_equation_" + verifierSuffix).c_str(), "BLEND_EQUATION_RGB and BLEND_DST", verifier)) FOR_EACH_VERIFIER( new BlendEquationAdvancedCase(m_context, (std::string() + "blend_equation_advanced_" + verifierSuffix).c_str(), "BLEND_EQUATION_RGB and BLEND_DST", verifier)) } } // namespace Functional } // namespace gles3 } // namespace deqp