| /*------------------------------------------------------------------------- |
| * 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) = 0; |
| |
| 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<GLint> 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<GLint64> 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) = 0; |
| |
| 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<GLint> 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<GLint64> 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<GLint> 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 |