blob: d647a5d9f772898a29910704265ee8fe33d1b4ff [file] [log] [blame]
/*-------------------------------------------------------------------------
* 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