/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 3.1 Module * ------------------------------------------------- * * Copyright 2015 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 "es31fIndexedStateQueryTests.hpp" #include "tcuTestLog.hpp" #include "tcuFormatUtil.hpp" #include "gluRenderContext.hpp" #include "gluCallLogWrapper.hpp" #include "gluStrUtil.hpp" #include "gluContextInfo.hpp" #include "gluObjectWrapper.hpp" #include "glwFunctions.hpp" #include "glwEnums.hpp" #include "glsStateQueryUtil.hpp" #include "deRandom.hpp" #include "deStringUtil.hpp" namespace deqp { namespace gles31 { namespace Functional { namespace { using namespace gls::StateQueryUtil; static const char* getVerifierSuffix (QueryType type) { switch (type) { case QUERY_INDEXED_BOOLEAN: return "getbooleani_v"; case QUERY_INDEXED_INTEGER: return "getintegeri_v"; case QUERY_INDEXED_INTEGER64: return "getinteger64i_v"; case QUERY_INDEXED_BOOLEAN_VEC4: return "getbooleani_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(DE_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 SampleMaskCase : public TestCase { public: SampleMaskCase (Context& context, const char* name, const char* desc, QueryType verifierType); private: void init (void); IterateResult iterate (void); const QueryType m_verifierType; int m_maxSampleMaskWords; }; SampleMaskCase::SampleMaskCase (Context& context, const char* name, const char* desc, QueryType verifierType) : TestCase (context, name, desc) , m_verifierType (verifierType) , m_maxSampleMaskWords (-1) { } void SampleMaskCase::init (void) { const glw::Functions& gl = m_context.getRenderContext().getFunctions(); gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &m_maxSampleMaskWords); GLU_EXPECT_NO_ERROR(gl.getError(), "query sample mask words"); // mask word count ok? if (m_maxSampleMaskWords <= 0) throw tcu::TestError("Minimum value of GL_MAX_SAMPLE_MASK_WORDS is 1. Got " + de::toString(m_maxSampleMaskWords)); m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_SAMPLE_MASK_WORDS = " << m_maxSampleMaskWords << tcu::TestLog::EndMessage; } SampleMaskCase::IterateResult SampleMaskCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); gl.enableLogging(true); // initial values { const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values"); for (int ndx = 0; ndx < m_maxSampleMaskWords; ++ndx) verifyStateIndexedInteger(result, gl, GL_SAMPLE_MASK_VALUE, ndx, -1, m_verifierType); } // fixed values { const tcu::ScopedLogSection section(m_testCtx.getLog(), "fixed", "Fixed values"); for (int ndx = 0; ndx < m_maxSampleMaskWords; ++ndx) { gl.glSampleMaski(ndx, 0); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glSampleMaski"); verifyStateIndexedInteger(result, gl, GL_SAMPLE_MASK_VALUE, ndx, 0, m_verifierType); } } // random masks { const int numRandomTest = 20; const tcu::ScopedLogSection section (m_testCtx.getLog(), "random", "Random values"); de::Random rnd (0x4312); for (int testNdx = 0; testNdx < numRandomTest; ++testNdx) { const glw::GLint maskIndex = (glw::GLint)(rnd.getUint32() % m_maxSampleMaskWords); glw::GLint mask = (glw::GLint)(rnd.getUint32()); gl.glSampleMaski(maskIndex, mask); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glSampleMaski"); verifyStateIndexedInteger(result, gl, GL_SAMPLE_MASK_VALUE, maskIndex, mask, m_verifierType); } } result.setTestContextResult(m_testCtx); return STOP; } class MinValueIndexed3Case : public TestCase { public: MinValueIndexed3Case (Context& context, const char* name, const char* desc, glw::GLenum target, const tcu::IVec3& ref, QueryType verifierType); private: IterateResult iterate (void); const glw::GLenum m_target; const tcu::IVec3 m_ref; const QueryType m_verifierType; }; MinValueIndexed3Case::MinValueIndexed3Case (Context& context, const char* name, const char* desc, glw::GLenum target, const tcu::IVec3& ref, QueryType verifierType) : TestCase (context, name, desc) , m_target (target) , m_ref (ref) , m_verifierType (verifierType) { } MinValueIndexed3Case::IterateResult MinValueIndexed3Case::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); gl.enableLogging(true); for (int ndx = 0; ndx < 3; ++ndx) { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Element", "Element " + de::toString(ndx)); verifyStateIndexedIntegerMin(result, gl, m_target, ndx, m_ref[ndx], m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class BufferBindingCase : public TestCase { public: BufferBindingCase (Context& context, const char* name, const char* desc, glw::GLenum queryTarget, glw::GLenum bufferTarget, glw::GLenum numBindingsTarget, QueryType verifierType); private: IterateResult iterate (void); const glw::GLenum m_queryTarget; const glw::GLenum m_bufferTarget; const glw::GLenum m_numBindingsTarget; const QueryType m_verifierType; }; BufferBindingCase::BufferBindingCase (Context& context, const char* name, const char* desc, glw::GLenum queryTarget, glw::GLenum bufferTarget, glw::GLenum numBindingsTarget, QueryType verifierType) : TestCase (context, name, desc) , m_queryTarget (queryTarget) , m_bufferTarget (bufferTarget) , m_numBindingsTarget (numBindingsTarget) , m_verifierType (verifierType) { } BufferBindingCase::IterateResult BufferBindingCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxBindings = -1; gl.enableLogging(true); gl.glGetIntegerv(m_numBindingsTarget, &maxBindings); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxBindings; ++ndx) verifyStateIndexedInteger(result, gl, m_queryTarget, ndx, 0, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Buffer bufferA (m_context.getRenderContext()); glu::Buffer bufferB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxBindings / 2; { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Generic", "After setting generic binding point"); gl.glBindBuffer(m_bufferTarget, *bufferA); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glBindBuffer"); verifyStateIndexedInteger(result, gl, m_queryTarget, 0, 0, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Indexed", "After setting with glBindBufferBase"); gl.glBindBufferBase(m_bufferTarget, ndxA, *bufferA); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glBindBufferBase"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxA, *bufferA, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Indexed", "After setting with glBindBufferRange"); gl.glBindBufferRange(m_bufferTarget, ndxB, *bufferB, 0, 8); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glBindBufferRange"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxB, *bufferB, m_verifierType); } if (ndxA != ndxB) { const tcu::ScopedLogSection section(m_testCtx.getLog(), "DifferentStates", "Original state did not change"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxA, *bufferA, m_verifierType); } } result.setTestContextResult(m_testCtx); return STOP; } class BufferStartCase : public TestCase { public: BufferStartCase (Context& context, const char* name, const char* desc, glw::GLenum queryTarget, glw::GLenum bufferTarget, glw::GLenum numBindingsTarget, QueryType verifierType); private: IterateResult iterate (void); const glw::GLenum m_queryTarget; const glw::GLenum m_bufferTarget; const glw::GLenum m_numBindingsTarget; const QueryType m_verifierType; }; BufferStartCase::BufferStartCase (Context& context, const char* name, const char* desc, glw::GLenum queryTarget, glw::GLenum bufferTarget, glw::GLenum numBindingsTarget, QueryType verifierType) : TestCase (context, name, desc) , m_queryTarget (queryTarget) , m_bufferTarget (bufferTarget) , m_numBindingsTarget (numBindingsTarget) , m_verifierType (verifierType) { } BufferStartCase::IterateResult BufferStartCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxBindings = -1; gl.enableLogging(true); gl.glGetIntegerv(m_numBindingsTarget, &maxBindings); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxBindings; ++ndx) verifyStateIndexedInteger(result, gl, m_queryTarget, ndx, 0, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Buffer bufferA (m_context.getRenderContext()); glu::Buffer bufferB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxBindings / 2; int offset = -1; if (m_bufferTarget == GL_ATOMIC_COUNTER_BUFFER) offset = 4; else if (m_bufferTarget == GL_SHADER_STORAGE_BUFFER) { gl.glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &offset); GLU_EXPECT_NO_ERROR(gl.glGetError(), "get align"); } else DE_ASSERT(false); TCU_CHECK(offset >= 0); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Generic", "After setting generic binding point"); gl.glBindBuffer(m_bufferTarget, *bufferA); gl.glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_READ); gl.glBindBuffer(m_bufferTarget, *bufferB); gl.glBufferData(m_bufferTarget, 32, DE_NULL, GL_DYNAMIC_READ); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen bufs"); verifyStateIndexedInteger(result, gl, m_queryTarget, 0, 0, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Indexed", "After setting with glBindBufferBase"); gl.glBindBufferBase(m_bufferTarget, ndxA, *bufferA); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind buf"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxA, 0, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Indexed", "After setting with glBindBufferRange"); gl.glBindBufferRange(m_bufferTarget, ndxB, *bufferB, offset, 8); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind buf"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxB, offset, m_verifierType); } if (ndxA != ndxB) { const tcu::ScopedLogSection section(m_testCtx.getLog(), "DifferentStates", "Original state did not change"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxA, 0, m_verifierType); } } result.setTestContextResult(m_testCtx); return STOP; } class BufferSizeCase : public TestCase { public: BufferSizeCase (Context& context, const char* name, const char* desc, glw::GLenum queryTarget, glw::GLenum bufferTarget, glw::GLenum numBindingsTarget, QueryType verifierType); private: IterateResult iterate (void); const glw::GLenum m_queryTarget; const glw::GLenum m_bufferTarget; const glw::GLenum m_numBindingsTarget; const QueryType m_verifierType; }; BufferSizeCase::BufferSizeCase (Context& context, const char* name, const char* desc, glw::GLenum queryTarget, glw::GLenum bufferTarget, glw::GLenum numBindingsTarget, QueryType verifierType) : TestCase (context, name, desc) , m_queryTarget (queryTarget) , m_bufferTarget (bufferTarget) , m_numBindingsTarget (numBindingsTarget) , m_verifierType (verifierType) { } BufferSizeCase::IterateResult BufferSizeCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxBindings = -1; gl.enableLogging(true); gl.glGetIntegerv(m_numBindingsTarget, &maxBindings); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxBindings; ++ndx) verifyStateIndexedInteger(result, gl, m_queryTarget, ndx, 0, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Buffer bufferA (m_context.getRenderContext()); glu::Buffer bufferB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxBindings / 2; { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Generic", "After setting generic binding point"); gl.glBindBuffer(m_bufferTarget, *bufferA); gl.glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_READ); gl.glBindBuffer(m_bufferTarget, *bufferB); gl.glBufferData(m_bufferTarget, 32, DE_NULL, GL_DYNAMIC_READ); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen bufs"); verifyStateIndexedInteger(result, gl, m_queryTarget, 0, 0, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Indexed", "After setting with glBindBufferBase"); gl.glBindBufferBase(m_bufferTarget, ndxA, *bufferA); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind buf"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxA, 0, m_verifierType); } { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Indexed", "After setting with glBindBufferRange"); gl.glBindBufferRange(m_bufferTarget, ndxB, *bufferB, 0, 8); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind buf"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxB, 8, m_verifierType); } if (ndxA != ndxB) { const tcu::ScopedLogSection section(m_testCtx.getLog(), "DifferentStates", "Original state did not change"); verifyStateIndexedInteger(result, gl, m_queryTarget, ndxA, 0, m_verifierType); } } result.setTestContextResult(m_testCtx); return STOP; } class ImageBindingNameCase : public TestCase { public: ImageBindingNameCase (Context& context, const char* name, const char* desc, QueryType verifierType); private: IterateResult iterate (void); const QueryType m_verifierType; }; ImageBindingNameCase::ImageBindingNameCase (Context& context, const char* name, const char* desc, QueryType verifierType) : TestCase (context, name, desc) , m_verifierType (verifierType) { } ImageBindingNameCase::IterateResult ImageBindingNameCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxImages = -1; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_IMAGE_UNITS, &maxImages); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxImages; ++ndx) verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_NAME, ndx, 0, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Texture textureA (m_context.getRenderContext()); glu::Texture textureB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxImages / 2; gl.glBindTexture(GL_TEXTURE_2D, *textureA); gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxA, *textureA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *textureB); gl.glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 32, 32, 4); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxB, *textureB, 0, GL_FALSE, 2, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_NAME, ndxA, *textureA, m_verifierType); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_NAME, ndxB, *textureB, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class ImageBindingLevelCase : public TestCase { public: ImageBindingLevelCase (Context& context, const char* name, const char* desc, QueryType verifierType); private: IterateResult iterate (void); const QueryType m_verifierType; }; ImageBindingLevelCase::ImageBindingLevelCase (Context& context, const char* name, const char* desc, QueryType verifierType) : TestCase (context, name, desc) , m_verifierType (verifierType) { } ImageBindingLevelCase::IterateResult ImageBindingLevelCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxImages = -1; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_IMAGE_UNITS, &maxImages); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxImages; ++ndx) verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_LEVEL, ndx, 0, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Texture textureA (m_context.getRenderContext()); glu::Texture textureB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxImages / 2; gl.glBindTexture(GL_TEXTURE_2D, *textureA); gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxA, *textureA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); gl.glBindTexture(GL_TEXTURE_2D, *textureB); gl.glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 32, 32); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxB, *textureB, 2, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_LEVEL, ndxA, 0, m_verifierType); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_LEVEL, ndxB, 2, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class ImageBindingLayeredCase : public TestCase { public: ImageBindingLayeredCase (Context& context, const char* name, const char* desc, QueryType verifierType); private: IterateResult iterate (void); const QueryType m_verifierType; }; ImageBindingLayeredCase::ImageBindingLayeredCase (Context& context, const char* name, const char* desc, QueryType verifierType) : TestCase (context, name, desc) , m_verifierType (verifierType) { } ImageBindingLayeredCase::IterateResult ImageBindingLayeredCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxImages = -1; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_IMAGE_UNITS, &maxImages); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxImages; ++ndx) verifyStateIndexedBoolean(result, gl, GL_IMAGE_BINDING_LAYERED, ndx, false, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Texture textureA (m_context.getRenderContext()); glu::Texture textureB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxImages / 2; gl.glBindTexture(GL_TEXTURE_2D, *textureA); gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxA, *textureA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *textureB); gl.glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 32, 32, 4); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxB, *textureB, 0, GL_TRUE, 2, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); verifyStateIndexedBoolean(result, gl, GL_IMAGE_BINDING_LAYERED, ndxA, false, m_verifierType); verifyStateIndexedBoolean(result, gl, GL_IMAGE_BINDING_LAYERED, ndxB, true, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class ImageBindingLayerCase : public TestCase { public: ImageBindingLayerCase (Context& context, const char* name, const char* desc, QueryType verifierType); private: IterateResult iterate (void); const QueryType m_verifierType; }; ImageBindingLayerCase::ImageBindingLayerCase (Context& context, const char* name, const char* desc, QueryType verifierType) : TestCase (context, name, desc) , m_verifierType (verifierType) { } ImageBindingLayerCase::IterateResult ImageBindingLayerCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxImages = -1; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_IMAGE_UNITS, &maxImages); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxImages; ++ndx) verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_LAYER, ndx, 0, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Texture textureA (m_context.getRenderContext()); glu::Texture textureB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxImages / 2; gl.glBindTexture(GL_TEXTURE_2D, *textureA); gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxA, *textureA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *textureB); gl.glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 32, 32, 4); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxB, *textureB, 0, GL_TRUE, 2, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_LAYER, ndxA, 0, m_verifierType); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_LAYER, ndxB, 2, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class ImageBindingAccessCase : public TestCase { public: ImageBindingAccessCase (Context& context, const char* name, const char* desc, QueryType verifierType); private: IterateResult iterate (void); const QueryType m_verifierType; }; ImageBindingAccessCase::ImageBindingAccessCase (Context& context, const char* name, const char* desc, QueryType verifierType) : TestCase (context, name, desc) , m_verifierType (verifierType) { } ImageBindingAccessCase::IterateResult ImageBindingAccessCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxImages = -1; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_IMAGE_UNITS, &maxImages); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxImages; ++ndx) verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_ACCESS, ndx, GL_READ_ONLY, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Texture textureA (m_context.getRenderContext()); glu::Texture textureB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxImages / 2; gl.glBindTexture(GL_TEXTURE_2D, *textureA); gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxA, *textureA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *textureB); gl.glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 32, 32, 4); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxB, *textureB, 0, GL_TRUE, 2, GL_READ_WRITE, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_ACCESS, ndxA, GL_READ_ONLY, m_verifierType); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_ACCESS, ndxB, GL_READ_WRITE, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } class ImageBindingFormatCase : public TestCase { public: ImageBindingFormatCase (Context& context, const char* name, const char* desc, QueryType verifierType); private: IterateResult iterate (void); const QueryType m_verifierType; }; ImageBindingFormatCase::ImageBindingFormatCase (Context& context, const char* name, const char* desc, QueryType verifierType) : TestCase (context, name, desc) , m_verifierType (verifierType) { } ImageBindingFormatCase::IterateResult ImageBindingFormatCase::iterate (void) { glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); int maxImages = -1; gl.enableLogging(true); gl.glGetIntegerv(GL_MAX_IMAGE_UNITS, &maxImages); GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv"); { const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value"); for (int ndx = 0; ndx < maxImages; ++ndx) if (glu::isContextTypeES(m_context.getRenderContext().getType())) verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_FORMAT, ndx, GL_R32UI, m_verifierType); else verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_FORMAT, ndx, GL_R8, m_verifierType); } { const tcu::ScopedLogSection superSection (m_testCtx.getLog(), "AfterSetting", "After setting"); glu::Texture textureA (m_context.getRenderContext()); glu::Texture textureB (m_context.getRenderContext()); const int ndxA = 0; const int ndxB = maxImages / 2; gl.glBindTexture(GL_TEXTURE_2D, *textureA); gl.glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxA, *textureA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8UI); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); gl.glBindTexture(GL_TEXTURE_2D_ARRAY, *textureB); gl.glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, 32, 32, 4); GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex"); gl.glBindImageTexture(ndxB, *textureB, 0, GL_TRUE, 2, GL_READ_WRITE, GL_R32F); GLU_EXPECT_NO_ERROR(gl.glGetError(), "bind unit"); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_FORMAT, ndxA, GL_RGBA8UI, m_verifierType); verifyStateIndexedInteger(result, gl, GL_IMAGE_BINDING_FORMAT, ndxB, GL_R32F, m_verifierType); } result.setTestContextResult(m_testCtx); return STOP; } 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: "); deInt32 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: "); deInt32 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 deUint32 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: "); deInt32 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 deUint32 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: "); deInt32 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 deUint32 blendEquations[] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX }; const deUint32 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: "); deInt32 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; } } // anonymous IndexedStateQueryTests::IndexedStateQueryTests (Context& context) : TestCaseGroup(context, "indexed", "Indexed state queries") { } IndexedStateQueryTests::~IndexedStateQueryTests (void) { } void IndexedStateQueryTests::init (void) { static const QueryType verifiers[] = { QUERY_INDEXED_BOOLEAN, QUERY_INDEXED_INTEGER, QUERY_INDEXED_INTEGER64 }; static const QueryType vec4Verifiers[] = { QUERY_INDEXED_BOOLEAN_VEC4, 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); \ } FOR_EACH_VERIFIER(new SampleMaskCase (m_context, (std::string() + "sample_mask_value_" + verifierSuffix).c_str(), "Test SAMPLE_MASK_VALUE", verifier)) FOR_EACH_VERIFIER(new MinValueIndexed3Case (m_context, (std::string() + "max_compute_work_group_count_" + verifierSuffix).c_str(), "Test MAX_COMPUTE_WORK_GROUP_COUNT", GL_MAX_COMPUTE_WORK_GROUP_COUNT, tcu::IVec3(65535,65535,65535), verifier)) FOR_EACH_VERIFIER(new MinValueIndexed3Case (m_context, (std::string() + "max_compute_work_group_size_" + verifierSuffix).c_str(), "Test MAX_COMPUTE_WORK_GROUP_SIZE", GL_MAX_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(128, 128, 64), verifier)) FOR_EACH_VERIFIER(new BufferBindingCase (m_context, (std::string() + "atomic_counter_buffer_binding_" + verifierSuffix).c_str(), "Test ATOMIC_COUNTER_BUFFER_BINDING", GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, verifier)) FOR_EACH_VERIFIER(new BufferStartCase (m_context, (std::string() + "atomic_counter_buffer_start_" + verifierSuffix).c_str(), "Test ATOMIC_COUNTER_BUFFER_START", GL_ATOMIC_COUNTER_BUFFER_START, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, verifier)) FOR_EACH_VERIFIER(new BufferSizeCase (m_context, (std::string() + "atomic_counter_buffer_size_" + verifierSuffix).c_str(), "Test ATOMIC_COUNTER_BUFFER_SIZE", GL_ATOMIC_COUNTER_BUFFER_SIZE, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, verifier)) FOR_EACH_VERIFIER(new BufferBindingCase (m_context, (std::string() + "shader_storage_buffer_binding_" + verifierSuffix).c_str(), "Test SHADER_STORAGE_BUFFER_BINDING", GL_SHADER_STORAGE_BUFFER_BINDING, GL_SHADER_STORAGE_BUFFER, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, verifier)) FOR_EACH_VERIFIER(new BufferStartCase (m_context, (std::string() + "shader_storage_buffer_start_" + verifierSuffix).c_str(), "Test SHADER_STORAGE_BUFFER_START", GL_SHADER_STORAGE_BUFFER_START, GL_SHADER_STORAGE_BUFFER, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, verifier)) FOR_EACH_VERIFIER(new BufferSizeCase (m_context, (std::string() + "shader_storage_buffer_size_" + verifierSuffix).c_str(), "Test SHADER_STORAGE_BUFFER_SIZE", GL_SHADER_STORAGE_BUFFER_SIZE, GL_SHADER_STORAGE_BUFFER, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, verifier)) FOR_EACH_VERIFIER(new ImageBindingNameCase (m_context, (std::string() + "image_binding_name_" + verifierSuffix).c_str(), "Test IMAGE_BINDING_NAME", verifier)) FOR_EACH_VERIFIER(new ImageBindingLevelCase (m_context, (std::string() + "image_binding_level_" + verifierSuffix).c_str(), "Test IMAGE_BINDING_LEVEL", verifier)) FOR_EACH_VERIFIER(new ImageBindingLayeredCase (m_context, (std::string() + "image_binding_layered_" + verifierSuffix).c_str(), "Test IMAGE_BINDING_LAYERED", verifier)) FOR_EACH_VERIFIER(new ImageBindingLayerCase (m_context, (std::string() + "image_binding_layer_" + verifierSuffix).c_str(), "Test IMAGE_BINDING_LAYER", verifier)) FOR_EACH_VERIFIER(new ImageBindingAccessCase (m_context, (std::string() + "image_binding_access_" + verifierSuffix).c_str(), "Test IMAGE_BINDING_ACCESS", verifier)) FOR_EACH_VERIFIER(new ImageBindingFormatCase (m_context, (std::string() + "image_binding_format_" + verifierSuffix).c_str(), "Test IMAGE_BINDING_FORMAT", verifier)) { const QueryType verifier = QUERY_INDEXED_ISENABLED; const char* verifierSuffix = getVerifierSuffix(verifier); this->addChild(new EnableBlendCase (m_context, (std::string() + "blend_" + verifierSuffix).c_str(), "BLEND", verifier)); } 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)) #undef FOR_EACH_VEC4_VERIFIER #undef FOR_EACH_VERIFIER } } // Functional } // gles31 } // deqp