1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2014-2016 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci */ /*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief 22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci/** 25e5c31af7Sopenharmony_ci * \file gl3cTransformFeedbackOverflowQueryTests.cpp 26e5c31af7Sopenharmony_ci * \brief Implements conformance tests for "Transform Feedback Overflow 27e5c31af7Sopenharmony_ci * Query" functionality. 28e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include "gl3cTransformFeedbackOverflowQueryTests.hpp" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include "deMath.h" 33e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp" 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 36e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 37e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 38e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include "tcuFuzzyImageCompare.hpp" 41e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 42e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 43e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 44e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ci#include "glw.h" 47e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cinamespace gl3cts 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ci/* 53e5c31af7Sopenharmony_ci Base class of all test cases of the feature. Enforces the requirements below: 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_ci * Check that the extension string is available. 56e5c31af7Sopenharmony_ci */ 57e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryBaseTest : public deqp::TestCase 58e5c31af7Sopenharmony_ci{ 59e5c31af7Sopenharmony_ciprotected: 60e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryBaseTest(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 61e5c31af7Sopenharmony_ci const char* name, const char* description) 62e5c31af7Sopenharmony_ci : TestCase(context, name, description), m_api(api), m_max_vertex_streams(0) 63e5c31af7Sopenharmony_ci { 64e5c31af7Sopenharmony_ci } 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_ci /* Checks whether the feature is supported. */ 67e5c31af7Sopenharmony_ci bool featureSupported() 68e5c31af7Sopenharmony_ci { 69e5c31af7Sopenharmony_ci if (m_api == TransformFeedbackOverflowQueryTests::API_GL_ARB_transform_feedback_overflow_query) 70e5c31af7Sopenharmony_ci { 71e5c31af7Sopenharmony_ci glu::ContextType contextType = m_context.getRenderContext().getType(); 72e5c31af7Sopenharmony_ci if (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_overflow_query") || 73e5c31af7Sopenharmony_ci glu::contextSupports(contextType, glu::ApiType::core(4, 6))) 74e5c31af7Sopenharmony_ci { 75e5c31af7Sopenharmony_ci return true; 76e5c31af7Sopenharmony_ci } 77e5c31af7Sopenharmony_ci } 78e5c31af7Sopenharmony_ci return false; 79e5c31af7Sopenharmony_ci } 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci /* Checks whether transform_feedback2 is supported. */ 82e5c31af7Sopenharmony_ci bool supportsTransformFeedback2() 83e5c31af7Sopenharmony_ci { 84e5c31af7Sopenharmony_ci return (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2") || 85e5c31af7Sopenharmony_ci glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE))); 86e5c31af7Sopenharmony_ci } 87e5c31af7Sopenharmony_ci 88e5c31af7Sopenharmony_ci /* Checks whether transform_feedback3 is supported. */ 89e5c31af7Sopenharmony_ci bool supportsTransformFeedback3() 90e5c31af7Sopenharmony_ci { 91e5c31af7Sopenharmony_ci return (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3") || 92e5c31af7Sopenharmony_ci glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE))); 93e5c31af7Sopenharmony_ci } 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci /* Checks whether gpu_shader5 is supported. */ 96e5c31af7Sopenharmony_ci bool supportsGpuShader5() 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci return (m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5") || 99e5c31af7Sopenharmony_ci glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE))); 100e5c31af7Sopenharmony_ci } 101e5c31af7Sopenharmony_ci 102e5c31af7Sopenharmony_ci /* Checks whether conditional_render_inverted is supported. */ 103e5c31af7Sopenharmony_ci bool supportsConditionalRenderInverted() 104e5c31af7Sopenharmony_ci { 105e5c31af7Sopenharmony_ci return (m_context.getContextInfo().isExtensionSupported("GL_ARB_conditional_render_inverted") || 106e5c31af7Sopenharmony_ci glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 5, glu::PROFILE_CORE))); 107e5c31af7Sopenharmony_ci } 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci /* Checks whether query_buffer_object are supported. */ 110e5c31af7Sopenharmony_ci bool supportsQueryBufferObject() 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci return (m_context.getContextInfo().isExtensionSupported("GL_ARB_query_buffer_object") || 113e5c31af7Sopenharmony_ci glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 4, glu::PROFILE_CORE))); 114e5c31af7Sopenharmony_ci } 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci /* Returns the maximum number of vertex streams. */ 117e5c31af7Sopenharmony_ci GLuint getMaxVertexStreams() const 118e5c31af7Sopenharmony_ci { 119e5c31af7Sopenharmony_ci return m_max_vertex_streams; 120e5c31af7Sopenharmony_ci } 121e5c31af7Sopenharmony_ci 122e5c31af7Sopenharmony_ci /* Basic test init, child classes must call it. */ 123e5c31af7Sopenharmony_ci virtual void init() 124e5c31af7Sopenharmony_ci { 125e5c31af7Sopenharmony_ci if (!featureSupported()) 126e5c31af7Sopenharmony_ci { 127e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Required transform_feedback_overflow_query extension is not supported"); 128e5c31af7Sopenharmony_ci } 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 131e5c31af7Sopenharmony_ci { 132e5c31af7Sopenharmony_ci m_max_vertex_streams = (GLuint)m_context.getContextInfo().getInt(GL_MAX_VERTEX_STREAMS); 133e5c31af7Sopenharmony_ci } 134e5c31af7Sopenharmony_ci } 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ciprotected: 137e5c31af7Sopenharmony_ci const TransformFeedbackOverflowQueryTests::API m_api; 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ciprivate: 140e5c31af7Sopenharmony_ci GLuint m_max_vertex_streams; 141e5c31af7Sopenharmony_ci}; 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci/* 144e5c31af7Sopenharmony_ci API Implementation Dependent State Test 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci * Check that calling GetQueryiv with target TRANSFORM_FEEDBACK_OVERFLOW 147e5c31af7Sopenharmony_ci and pname QUERY_COUNTER_BITS returns a non-negative value without error. 148e5c31af7Sopenharmony_ci 149e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 150e5c31af7Sopenharmony_ci GetQueryiv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW and pname 151e5c31af7Sopenharmony_ci QUERY_COUNTER_BITS returns a non-negative value without error. 152e5c31af7Sopenharmony_ci */ 153e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryImplDepState : public TransformFeedbackOverflowQueryBaseTest 154e5c31af7Sopenharmony_ci{ 155e5c31af7Sopenharmony_cipublic: 156e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryImplDepState(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 157e5c31af7Sopenharmony_ci const char* name) 158e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryBaseTest( 159e5c31af7Sopenharmony_ci context, api, name, 160e5c31af7Sopenharmony_ci "Tests whether the implementation dependent state defined by the feature matches the requirements.") 161e5c31af7Sopenharmony_ci { 162e5c31af7Sopenharmony_ci } 163e5c31af7Sopenharmony_ci 164e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 165e5c31af7Sopenharmony_ci IterateResult iterate() 166e5c31af7Sopenharmony_ci { 167e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 168e5c31af7Sopenharmony_ci GLint counterBits; 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci gl.getQueryiv(GL_TRANSFORM_FEEDBACK_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits); 171e5c31af7Sopenharmony_ci if (counterBits < 0) 172e5c31af7Sopenharmony_ci { 173e5c31af7Sopenharmony_ci TCU_FAIL("Value of QUERY_COUNTER_BITS for query target TRANSFORM_FEEDBACK_OVERFLOW is invalid"); 174e5c31af7Sopenharmony_ci } 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 177e5c31af7Sopenharmony_ci { 178e5c31af7Sopenharmony_ci gl.getQueryiv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits); 179e5c31af7Sopenharmony_ci if (counterBits < 0) 180e5c31af7Sopenharmony_ci { 181e5c31af7Sopenharmony_ci TCU_FAIL("Value of QUERY_COUNTER_BITS for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW is invalid"); 182e5c31af7Sopenharmony_ci } 183e5c31af7Sopenharmony_ci } 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 186e5c31af7Sopenharmony_ci 187e5c31af7Sopenharmony_ci return STOP; 188e5c31af7Sopenharmony_ci } 189e5c31af7Sopenharmony_ci}; 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci/* 192e5c31af7Sopenharmony_ci Base class for all test cases of the feature that verify newly introduced context state. 193e5c31af7Sopenharmony_ci */ 194e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryContextStateBase : public TransformFeedbackOverflowQueryBaseTest 195e5c31af7Sopenharmony_ci{ 196e5c31af7Sopenharmony_ciprotected: 197e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryContextStateBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 198e5c31af7Sopenharmony_ci const char* name, const char* description) 199e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryBaseTest(context, api, name, description) 200e5c31af7Sopenharmony_ci { 201e5c31af7Sopenharmony_ci } 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci /* Returns whether CURRENT_QUERY state for the specified target and index matches the given value. */ 204e5c31af7Sopenharmony_ci bool verifyCurrentQueryState(GLenum target, GLuint index, GLuint value) 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 207e5c31af7Sopenharmony_ci GLint expected = (GLint)value; 208e5c31af7Sopenharmony_ci GLint actual; 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ci // Use GetQueryIndexediv by default 211e5c31af7Sopenharmony_ci gl.getQueryIndexediv(target, index, GL_CURRENT_QUERY, &actual); 212e5c31af7Sopenharmony_ci if (actual != expected) 213e5c31af7Sopenharmony_ci { 214e5c31af7Sopenharmony_ci return false; 215e5c31af7Sopenharmony_ci } 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_ci if (index == 0) 218e5c31af7Sopenharmony_ci { 219e5c31af7Sopenharmony_ci // If index is zero then GetQueryiv should also return the expected value 220e5c31af7Sopenharmony_ci gl.getQueryiv(target, GL_CURRENT_QUERY, &actual); 221e5c31af7Sopenharmony_ci if (actual != expected) 222e5c31af7Sopenharmony_ci { 223e5c31af7Sopenharmony_ci return false; 224e5c31af7Sopenharmony_ci } 225e5c31af7Sopenharmony_ci } 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci return true; 228e5c31af7Sopenharmony_ci } 229e5c31af7Sopenharmony_ci}; 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci/* 232e5c31af7Sopenharmony_ci API Default Context State Test 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci * Check that calling GetQueryiv with target TRANSFORM_FEEDBACK_OVERFLOW 235e5c31af7Sopenharmony_ci and pname CURRENT_QUERY returns zero by default. 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 238e5c31af7Sopenharmony_ci GetQueryIndexediv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW and 239e5c31af7Sopenharmony_ci pname CURRENT_QUERY returns zero for any index between zero and MAX_- 240e5c31af7Sopenharmony_ci VERTEX_STREAMS. 241e5c31af7Sopenharmony_ci */ 242e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryDefaultState : public TransformFeedbackOverflowQueryContextStateBase 243e5c31af7Sopenharmony_ci{ 244e5c31af7Sopenharmony_cipublic: 245e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryDefaultState(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 246e5c31af7Sopenharmony_ci const char* name) 247e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryContextStateBase( 248e5c31af7Sopenharmony_ci context, api, name, 249e5c31af7Sopenharmony_ci "Tests whether the new context state defined by the feature has the expected default values.") 250e5c31af7Sopenharmony_ci { 251e5c31af7Sopenharmony_ci } 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 254e5c31af7Sopenharmony_ci IterateResult iterate() 255e5c31af7Sopenharmony_ci { 256e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, 0)) 257e5c31af7Sopenharmony_ci { 258e5c31af7Sopenharmony_ci TCU_FAIL("Default value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is non-zero"); 259e5c31af7Sopenharmony_ci } 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 262e5c31af7Sopenharmony_ci { 263e5c31af7Sopenharmony_ci for (GLuint i = 0; i < getMaxVertexStreams(); ++i) 264e5c31af7Sopenharmony_ci { 265e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 0, 0)) 266e5c31af7Sopenharmony_ci { 267e5c31af7Sopenharmony_ci TCU_FAIL("Default value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW " 268e5c31af7Sopenharmony_ci "is non-zero"); 269e5c31af7Sopenharmony_ci } 270e5c31af7Sopenharmony_ci } 271e5c31af7Sopenharmony_ci } 272e5c31af7Sopenharmony_ci 273e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ci return STOP; 276e5c31af7Sopenharmony_ci } 277e5c31af7Sopenharmony_ci}; 278e5c31af7Sopenharmony_ci 279e5c31af7Sopenharmony_ci/* 280e5c31af7Sopenharmony_ci API Context State Update Test 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci * Check that after a successful call to BeginQuery with target TRANSFORM_- 283e5c31af7Sopenharmony_ci FEEDBACK_OVERFLOW_ARB calling GetQueryiv with the same target and with 284e5c31af7Sopenharmony_ci pname CURRENT_QUERY returns the name of the query previously passed to 285e5c31af7Sopenharmony_ci BeginQuery. Also check that after calling EndQuery with the same target 286e5c31af7Sopenharmony_ci GetQueryiv returns zero for the same parameters. 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that after a 289e5c31af7Sopenharmony_ci successful call to BeginQueryIndexed with target TRANSFORM_FEEDBACK_- 290e5c31af7Sopenharmony_ci STREAM_OVERFLOW_ARB calling GetQueryIndexediv with the same target and 291e5c31af7Sopenharmony_ci with pname CURRENT_QUERY returns the name of the query previously passed 292e5c31af7Sopenharmony_ci to BeginQueryIndexed if the index parameters match and otherwise it 293e5c31af7Sopenharmony_ci returns zero. Also check that after calling EndQueryIndexed with the 294e5c31af7Sopenharmony_ci same target and index GetQueryIndexediv returns zero for the same 295e5c31af7Sopenharmony_ci parameters for all indices. Indices used should be between zero and 296e5c31af7Sopenharmony_ci MAX_VERTEX_STREAMS. 297e5c31af7Sopenharmony_ci */ 298e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryStateUpdate : public TransformFeedbackOverflowQueryContextStateBase 299e5c31af7Sopenharmony_ci{ 300e5c31af7Sopenharmony_cipublic: 301e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryStateUpdate(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 302e5c31af7Sopenharmony_ci const char* name) 303e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryContextStateBase( 304e5c31af7Sopenharmony_ci context, api, name, 305e5c31af7Sopenharmony_ci "Tests whether the new context state defined by the feature is correctly updated after a successful " 306e5c31af7Sopenharmony_ci "call to {Begin|End}Query[Indexed] if the target of the query is one of the newly introduced ones.") 307e5c31af7Sopenharmony_ci , m_overflow_query(0) 308e5c31af7Sopenharmony_ci , m_stream_overflow_query(0) 309e5c31af7Sopenharmony_ci { 310e5c31af7Sopenharmony_ci } 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci /* Test case init. */ 313e5c31af7Sopenharmony_ci virtual void init() 314e5c31af7Sopenharmony_ci { 315e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryContextStateBase::init(); 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci gl.genQueries(1, &m_overflow_query); 320e5c31af7Sopenharmony_ci gl.genQueries(1, &m_stream_overflow_query); 321e5c31af7Sopenharmony_ci } 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_ci /* Test case deinit */ 324e5c31af7Sopenharmony_ci virtual void deinit() 325e5c31af7Sopenharmony_ci { 326e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 327e5c31af7Sopenharmony_ci 328e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_overflow_query); 329e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_stream_overflow_query); 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryContextStateBase::deinit(); 332e5c31af7Sopenharmony_ci } 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 335e5c31af7Sopenharmony_ci IterateResult iterate() 336e5c31af7Sopenharmony_ci { 337e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_ci // Call BeginQuery 340e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query); 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_ci // Verify that CURRENT_QUERY is set to the name of the query 343e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_overflow_query)) 344e5c31af7Sopenharmony_ci { 345e5c31af7Sopenharmony_ci TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is not updated properly " 346e5c31af7Sopenharmony_ci "after a call to BeginQuery"); 347e5c31af7Sopenharmony_ci } 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci // Call EndQuery 350e5c31af7Sopenharmony_ci gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW); 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci // Verify that CURRENT_QUERY is reset to zero 353e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, 0)) 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is not reset properly " 356e5c31af7Sopenharmony_ci "after a call to EndQuery"); 357e5c31af7Sopenharmony_ci } 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 360e5c31af7Sopenharmony_ci { 361e5c31af7Sopenharmony_ci for (GLuint i = 0; i < getMaxVertexStreams(); ++i) 362e5c31af7Sopenharmony_ci { 363e5c31af7Sopenharmony_ci // Call BeginQueryIndexed with specified index 364e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_stream_overflow_query); 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci // Verify that CURRENT_QUERY is set to the name of the query for the specified index, but remains zero for other indices 367e5c31af7Sopenharmony_ci for (GLuint j = 0; j < getMaxVertexStreams(); ++j) 368e5c31af7Sopenharmony_ci { 369e5c31af7Sopenharmony_ci if (i == j) 370e5c31af7Sopenharmony_ci { 371e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, m_stream_overflow_query)) 372e5c31af7Sopenharmony_ci { 373e5c31af7Sopenharmony_ci TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW " 374e5c31af7Sopenharmony_ci "is not updated properly after a call to BeginQueryIndexed"); 375e5c31af7Sopenharmony_ci } 376e5c31af7Sopenharmony_ci } 377e5c31af7Sopenharmony_ci else 378e5c31af7Sopenharmony_ci { 379e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0)) 380e5c31af7Sopenharmony_ci { 381e5c31af7Sopenharmony_ci TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW " 382e5c31af7Sopenharmony_ci "is incorrectly updated for an unrelated vertex stream" 383e5c31af7Sopenharmony_ci "index after a call to BeginQueryIndexed"); 384e5c31af7Sopenharmony_ci } 385e5c31af7Sopenharmony_ci } 386e5c31af7Sopenharmony_ci } 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci // Call EndQueryIndexed with specified index 389e5c31af7Sopenharmony_ci gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i); 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_ci // Verify that CURRENT_QUERY is reset to zero for the specified index and still remains zero for other indices 392e5c31af7Sopenharmony_ci for (GLuint j = 0; j < getMaxVertexStreams(); ++j) 393e5c31af7Sopenharmony_ci { 394e5c31af7Sopenharmony_ci if (i == j) 395e5c31af7Sopenharmony_ci { 396e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0)) 397e5c31af7Sopenharmony_ci { 398e5c31af7Sopenharmony_ci TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW " 399e5c31af7Sopenharmony_ci "is not reset properly after a call to EndQueryIndexed"); 400e5c31af7Sopenharmony_ci } 401e5c31af7Sopenharmony_ci } 402e5c31af7Sopenharmony_ci else 403e5c31af7Sopenharmony_ci { 404e5c31af7Sopenharmony_ci if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0)) 405e5c31af7Sopenharmony_ci { 406e5c31af7Sopenharmony_ci TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW " 407e5c31af7Sopenharmony_ci "is incorrectly updated for an unrelated vertex stream" 408e5c31af7Sopenharmony_ci "index after a call to EndQueryIndexed"); 409e5c31af7Sopenharmony_ci } 410e5c31af7Sopenharmony_ci } 411e5c31af7Sopenharmony_ci } 412e5c31af7Sopenharmony_ci } 413e5c31af7Sopenharmony_ci } 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci return STOP; 418e5c31af7Sopenharmony_ci } 419e5c31af7Sopenharmony_ci 420e5c31af7Sopenharmony_ciprotected: 421e5c31af7Sopenharmony_ci GLuint m_overflow_query; 422e5c31af7Sopenharmony_ci GLuint m_stream_overflow_query; 423e5c31af7Sopenharmony_ci}; 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci/* 426e5c31af7Sopenharmony_ci Base class for all test cases of the feature that verify various error scenarios. 427e5c31af7Sopenharmony_ci */ 428e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorBase : public TransformFeedbackOverflowQueryBaseTest 429e5c31af7Sopenharmony_ci{ 430e5c31af7Sopenharmony_ciprotected: 431e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 432e5c31af7Sopenharmony_ci const char* name, const char* description) 433e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryBaseTest(context, api, name, description), m_case_name(0) 434e5c31af7Sopenharmony_ci { 435e5c31af7Sopenharmony_ci } 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_ci /* Starts a new error scenario sub-test with the given name. The name is used in error messages if the sub-test fails. */ 438e5c31af7Sopenharmony_ci void startTest(const char* caseName) 439e5c31af7Sopenharmony_ci { 440e5c31af7Sopenharmony_ci m_case_name = caseName; 441e5c31af7Sopenharmony_ci } 442e5c31af7Sopenharmony_ci 443e5c31af7Sopenharmony_ci /* Verifies whether the actually generated error matches that of the expected one. If not then it triggers the failure 444e5c31af7Sopenharmony_ci of the test case with the sub-case name used as the failure message. */ 445e5c31af7Sopenharmony_ci void verifyError(GLenum expectedError) 446e5c31af7Sopenharmony_ci { 447e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 448e5c31af7Sopenharmony_ci 449e5c31af7Sopenharmony_ci GLenum actualError = gl.getError(); 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_ci if (actualError != expectedError) 452e5c31af7Sopenharmony_ci { 453e5c31af7Sopenharmony_ci TCU_FAIL(m_case_name); 454e5c31af7Sopenharmony_ci } 455e5c31af7Sopenharmony_ci } 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ciprivate: 458e5c31af7Sopenharmony_ci const char* m_case_name; 459e5c31af7Sopenharmony_ci}; 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci/* 462e5c31af7Sopenharmony_ci API Invalid Index Error Test 463e5c31af7Sopenharmony_ci 464e5c31af7Sopenharmony_ci * Check that calling GetQueryIndexediv with target TRANSFORM_FEEDBACK_- 465e5c31af7Sopenharmony_ci OVERFLOW_ARB and a non-zero index generates an INVALID_VALUE error. 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 468e5c31af7Sopenharmony_ci GetQueryIndexediv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW 469e5c31af7Sopenharmony_ci and an index greater than or equal to MAX_VERTEX_STREAMS generates an 470e5c31af7Sopenharmony_ci INVALID_VALUE error. 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_ci * Check that calling BeginQueryIndexed with target TRANSFORM_FEEDBACK_- 473e5c31af7Sopenharmony_ci OVERFLOW_ARB and a non-zero index generates an INVALID_VALUE error. 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 476e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW 477e5c31af7Sopenharmony_ci and an index greater than or equal to MAX_VERTEX_STREAMS generates an 478e5c31af7Sopenharmony_ci INVALID_VALUE error. 479e5c31af7Sopenharmony_ci */ 480e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorInvalidIndex : public TransformFeedbackOverflowQueryErrorBase 481e5c31af7Sopenharmony_ci{ 482e5c31af7Sopenharmony_cipublic: 483e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorInvalidIndex(deqp::Context& context, 484e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, const char* name) 485e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryErrorBase( 486e5c31af7Sopenharmony_ci context, api, name, "Verifies whether an INVALID_VALUE error is properly generated if GetQueryIndexediv " 487e5c31af7Sopenharmony_ci "or BeginQueryIndexed is called " 488e5c31af7Sopenharmony_ci "with an invalid index when using the new targets introduced by the feature.") 489e5c31af7Sopenharmony_ci , m_query(0) 490e5c31af7Sopenharmony_ci { 491e5c31af7Sopenharmony_ci } 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci /* Test case init. */ 494e5c31af7Sopenharmony_ci virtual void init() 495e5c31af7Sopenharmony_ci { 496e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::init(); 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_ci gl.genQueries(1, &m_query); 501e5c31af7Sopenharmony_ci } 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci /* Test case deinit */ 504e5c31af7Sopenharmony_ci virtual void deinit() 505e5c31af7Sopenharmony_ci { 506e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 507e5c31af7Sopenharmony_ci 508e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_query); 509e5c31af7Sopenharmony_ci 510e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::deinit(); 511e5c31af7Sopenharmony_ci } 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 514e5c31af7Sopenharmony_ci IterateResult iterate() 515e5c31af7Sopenharmony_ci { 516e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 517e5c31af7Sopenharmony_ci GLint value; 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci startTest("GetQueryIndexediv must generate INVALID_VALUE if <target> is " 520e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_OVERFLOW and <index> is non-zero."); 521e5c31af7Sopenharmony_ci 522e5c31af7Sopenharmony_ci for (GLuint i = 1; i < getMaxVertexStreams(); ++i) 523e5c31af7Sopenharmony_ci { 524e5c31af7Sopenharmony_ci gl.getQueryIndexediv(GL_TRANSFORM_FEEDBACK_OVERFLOW, i, GL_CURRENT_QUERY, &value); 525e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE); 526e5c31af7Sopenharmony_ci } 527e5c31af7Sopenharmony_ci 528e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 529e5c31af7Sopenharmony_ci { 530e5c31af7Sopenharmony_ci startTest("GetQueryIndexediv must generate INVALID_VALUE if <target> is " 531e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and <index> is greater " 532e5c31af7Sopenharmony_ci "than or equal to MAX_VERTEX_STREAMS."); 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci for (GLuint i = getMaxVertexStreams(); i < getMaxVertexStreams() + 4; ++i) 535e5c31af7Sopenharmony_ci { 536e5c31af7Sopenharmony_ci gl.getQueryIndexediv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, GL_CURRENT_QUERY, &value); 537e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE); 538e5c31af7Sopenharmony_ci } 539e5c31af7Sopenharmony_ci } 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ci startTest("BeginQueryIndexed must generate INVALID_VALUE if <target> is " 542e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_OVERFLOW and <index> is non-zero."); 543e5c31af7Sopenharmony_ci 544e5c31af7Sopenharmony_ci for (GLuint i = 1; i < getMaxVertexStreams(); ++i) 545e5c31af7Sopenharmony_ci { 546e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, i, m_query); 547e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE); 548e5c31af7Sopenharmony_ci } 549e5c31af7Sopenharmony_ci 550e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 551e5c31af7Sopenharmony_ci { 552e5c31af7Sopenharmony_ci startTest("BeginQueryIndexed must generate INVALID_VALUE if <target> is " 553e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and <index> is greater " 554e5c31af7Sopenharmony_ci "than or equal to MAX_VERTEX_STREAMS."); 555e5c31af7Sopenharmony_ci 556e5c31af7Sopenharmony_ci for (GLuint i = getMaxVertexStreams(); i < getMaxVertexStreams() + 4; ++i) 557e5c31af7Sopenharmony_ci { 558e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_query); 559e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE); 560e5c31af7Sopenharmony_ci } 561e5c31af7Sopenharmony_ci } 562e5c31af7Sopenharmony_ci 563e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ci return STOP; 566e5c31af7Sopenharmony_ci } 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_ciprotected: 569e5c31af7Sopenharmony_ci GLuint m_query; 570e5c31af7Sopenharmony_ci}; 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ci/* 573e5c31af7Sopenharmony_ci API Already Active Error Test 574e5c31af7Sopenharmony_ci 575e5c31af7Sopenharmony_ci * Check that calling BeginQuery with target TRANSFORM_FEEDBACK_OVERFLOW 576e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if there is already an active 577e5c31af7Sopenharmony_ci query for TRANSFORM_FEEDBACK_OVERFLOW. 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 580e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW 581e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if there is already an active 582e5c31af7Sopenharmony_ci query for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified 583e5c31af7Sopenharmony_ci index. 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 586e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW 587e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if the specified query is already 588e5c31af7Sopenharmony_ci active on another TRANSFORM_FEEDBACK_STREAM_OVERFLOW target with 589e5c31af7Sopenharmony_ci a different index. 590e5c31af7Sopenharmony_ci */ 591e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorAlreadyActive : public TransformFeedbackOverflowQueryErrorBase 592e5c31af7Sopenharmony_ci{ 593e5c31af7Sopenharmony_cipublic: 594e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorAlreadyActive(deqp::Context& context, 595e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, const char* name) 596e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryErrorBase(context, api, name, 597e5c31af7Sopenharmony_ci "Verifies whether an INVALID_OPERATION error is properly generated " 598e5c31af7Sopenharmony_ci "if BeginQuery[Indexed] is used to try to start " 599e5c31af7Sopenharmony_ci "a query on an index that has already a query active, or the query " 600e5c31af7Sopenharmony_ci "object itself is active on another index.") 601e5c31af7Sopenharmony_ci , m_query(0) 602e5c31af7Sopenharmony_ci , m_active_overflow_query(0) 603e5c31af7Sopenharmony_ci , m_active_stream_overflow_query(0) 604e5c31af7Sopenharmony_ci , m_active_query_stream_index(0) 605e5c31af7Sopenharmony_ci { 606e5c31af7Sopenharmony_ci } 607e5c31af7Sopenharmony_ci 608e5c31af7Sopenharmony_ci /* Test case init. */ 609e5c31af7Sopenharmony_ci virtual void init() 610e5c31af7Sopenharmony_ci { 611e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::init(); 612e5c31af7Sopenharmony_ci 613e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ci gl.genQueries(1, &m_query); 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci gl.genQueries(1, &m_active_overflow_query); 618e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_active_overflow_query); 619e5c31af7Sopenharmony_ci 620e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 621e5c31af7Sopenharmony_ci { 622e5c31af7Sopenharmony_ci gl.genQueries(1, &m_active_stream_overflow_query); 623e5c31af7Sopenharmony_ci m_active_query_stream_index = 2; 624e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index, 625e5c31af7Sopenharmony_ci m_active_stream_overflow_query); 626e5c31af7Sopenharmony_ci } 627e5c31af7Sopenharmony_ci } 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci /* Test case deinit */ 630e5c31af7Sopenharmony_ci virtual void deinit() 631e5c31af7Sopenharmony_ci { 632e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 633e5c31af7Sopenharmony_ci 634e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 635e5c31af7Sopenharmony_ci { 636e5c31af7Sopenharmony_ci gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index); 637e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_active_stream_overflow_query); 638e5c31af7Sopenharmony_ci } 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW); 641e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_active_overflow_query); 642e5c31af7Sopenharmony_ci 643e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_query); 644e5c31af7Sopenharmony_ci 645e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::deinit(); 646e5c31af7Sopenharmony_ci } 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 649e5c31af7Sopenharmony_ci IterateResult iterate() 650e5c31af7Sopenharmony_ci { 651e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is " 654e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_OVERFLOW and there is already an active " 655e5c31af7Sopenharmony_ci "query for TRANSFORM_FEEDBACK_ARB."); 656e5c31af7Sopenharmony_ci 657e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_query); 658e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 659e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_query); 660e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 661e5c31af7Sopenharmony_ci 662e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 663e5c31af7Sopenharmony_ci { 664e5c31af7Sopenharmony_ci startTest("BeginQueryIndexed must generate INVALID_OPERATION if <target> is " 665e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and there is already an active " 666e5c31af7Sopenharmony_ci "query for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified index."); 667e5c31af7Sopenharmony_ci 668e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index, m_query); 669e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is " 672e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and the specified query is " 673e5c31af7Sopenharmony_ci "already active on another TRANSFORM_FEEDBACK_STREAM_OVERFLOW " 674e5c31af7Sopenharmony_ci "target with a different index."); 675e5c31af7Sopenharmony_ci 676e5c31af7Sopenharmony_ci for (GLuint i = 0; i < getMaxVertexStreams(); ++i) 677e5c31af7Sopenharmony_ci { 678e5c31af7Sopenharmony_ci if (i != m_active_query_stream_index) 679e5c31af7Sopenharmony_ci { 680e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_active_stream_overflow_query); 681e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 682e5c31af7Sopenharmony_ci 683e5c31af7Sopenharmony_ci if (i == 0) 684e5c31af7Sopenharmony_ci { 685e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_stream_overflow_query); 686e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 687e5c31af7Sopenharmony_ci } 688e5c31af7Sopenharmony_ci } 689e5c31af7Sopenharmony_ci } 690e5c31af7Sopenharmony_ci } 691e5c31af7Sopenharmony_ci 692e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_ci return STOP; 695e5c31af7Sopenharmony_ci } 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ciprotected: 698e5c31af7Sopenharmony_ci GLuint m_query; 699e5c31af7Sopenharmony_ci GLuint m_active_overflow_query; 700e5c31af7Sopenharmony_ci GLuint m_active_stream_overflow_query; 701e5c31af7Sopenharmony_ci GLuint m_active_query_stream_index; 702e5c31af7Sopenharmony_ci}; 703e5c31af7Sopenharmony_ci 704e5c31af7Sopenharmony_ci/* 705e5c31af7Sopenharmony_ci API Incompatible Target Error Test 706e5c31af7Sopenharmony_ci 707e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 708e5c31af7Sopenharmony_ci BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW 709e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if the specified query was 710e5c31af7Sopenharmony_ci previously used as a TRANSFORM_FEEDBACK_OVERFLOW query. Also check 711e5c31af7Sopenharmony_ci the other way around. 712e5c31af7Sopenharmony_ci */ 713e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorIncompatibleTarget : public TransformFeedbackOverflowQueryErrorBase 714e5c31af7Sopenharmony_ci{ 715e5c31af7Sopenharmony_cipublic: 716e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorIncompatibleTarget(deqp::Context& context, 717e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, 718e5c31af7Sopenharmony_ci const char* name) 719e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryErrorBase(context, api, name, 720e5c31af7Sopenharmony_ci "Verifies whether an INVALID_OPERATION error is properly generated " 721e5c31af7Sopenharmony_ci "if BeginQuery[Indexed] is called with one of " 722e5c31af7Sopenharmony_ci "the newly introduced query targets but one that is different than " 723e5c31af7Sopenharmony_ci "that used earlier on the same query object.") 724e5c31af7Sopenharmony_ci , m_overflow_query(0) 725e5c31af7Sopenharmony_ci , m_stream_overflow_query(0) 726e5c31af7Sopenharmony_ci , m_incompatible_query(0) 727e5c31af7Sopenharmony_ci { 728e5c31af7Sopenharmony_ci } 729e5c31af7Sopenharmony_ci 730e5c31af7Sopenharmony_ci /* Test case init. */ 731e5c31af7Sopenharmony_ci virtual void init() 732e5c31af7Sopenharmony_ci { 733e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::init(); 734e5c31af7Sopenharmony_ci 735e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 736e5c31af7Sopenharmony_ci 737e5c31af7Sopenharmony_ci gl.genQueries(1, &m_incompatible_query); 738e5c31af7Sopenharmony_ci gl.beginQuery(GL_SAMPLES_PASSED, m_incompatible_query); 739e5c31af7Sopenharmony_ci gl.endQuery(GL_SAMPLES_PASSED); 740e5c31af7Sopenharmony_ci 741e5c31af7Sopenharmony_ci gl.genQueries(1, &m_overflow_query); 742e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query); 743e5c31af7Sopenharmony_ci gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW); 744e5c31af7Sopenharmony_ci 745e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 746e5c31af7Sopenharmony_ci { 747e5c31af7Sopenharmony_ci gl.genQueries(1, &m_stream_overflow_query); 748e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_stream_overflow_query); 749e5c31af7Sopenharmony_ci gl.endQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW); 750e5c31af7Sopenharmony_ci } 751e5c31af7Sopenharmony_ci } 752e5c31af7Sopenharmony_ci 753e5c31af7Sopenharmony_ci /* Test case deinit */ 754e5c31af7Sopenharmony_ci virtual void deinit() 755e5c31af7Sopenharmony_ci { 756e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 757e5c31af7Sopenharmony_ci 758e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_incompatible_query); 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_overflow_query); 761e5c31af7Sopenharmony_ci 762e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 763e5c31af7Sopenharmony_ci { 764e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_stream_overflow_query); 765e5c31af7Sopenharmony_ci } 766e5c31af7Sopenharmony_ci 767e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::deinit(); 768e5c31af7Sopenharmony_ci } 769e5c31af7Sopenharmony_ci 770e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 771e5c31af7Sopenharmony_ci IterateResult iterate() 772e5c31af7Sopenharmony_ci { 773e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 774e5c31af7Sopenharmony_ci 775e5c31af7Sopenharmony_ci startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is " 776e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_OVERFLOW and the specified query was " 777e5c31af7Sopenharmony_ci "previously used with another target."); 778e5c31af7Sopenharmony_ci 779e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_incompatible_query); 780e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 781e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_incompatible_query); 782e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 783e5c31af7Sopenharmony_ci 784e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 785e5c31af7Sopenharmony_ci { 786e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_stream_overflow_query); 787e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 788e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_stream_overflow_query); 789e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 790e5c31af7Sopenharmony_ci 791e5c31af7Sopenharmony_ci startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is " 792e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and the specified query " 793e5c31af7Sopenharmony_ci "was previously used with another target."); 794e5c31af7Sopenharmony_ci 795e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_incompatible_query); 796e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 797e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 2, m_incompatible_query); 798e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_overflow_query); 801e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 802e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 2, m_overflow_query); 803e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 804e5c31af7Sopenharmony_ci } 805e5c31af7Sopenharmony_ci 806e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 807e5c31af7Sopenharmony_ci 808e5c31af7Sopenharmony_ci return STOP; 809e5c31af7Sopenharmony_ci } 810e5c31af7Sopenharmony_ci 811e5c31af7Sopenharmony_ciprotected: 812e5c31af7Sopenharmony_ci GLuint m_overflow_query; 813e5c31af7Sopenharmony_ci GLuint m_stream_overflow_query; 814e5c31af7Sopenharmony_ci GLuint m_incompatible_query; 815e5c31af7Sopenharmony_ci}; 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci/* 818e5c31af7Sopenharmony_ci API No Query Active Error Test 819e5c31af7Sopenharmony_ci 820e5c31af7Sopenharmony_ci * Check that calling EndQuery with target TRANSFORM_FEEDBACK_OVERFLOW 821e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if no query is active for 822e5c31af7Sopenharmony_ci TRANSFORM_FEEDBACK_OVERFLOW. 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling 825e5c31af7Sopenharmony_ci EndQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW 826e5c31af7Sopenharmony_ci generates an INVALID_OPERATION error if no query is active for 827e5c31af7Sopenharmony_ci TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified index, even 828e5c31af7Sopenharmony_ci if there is an active query for another index. 829e5c31af7Sopenharmony_ci */ 830e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryErrorNoActiveQuery : public TransformFeedbackOverflowQueryErrorBase 831e5c31af7Sopenharmony_ci{ 832e5c31af7Sopenharmony_cipublic: 833e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorNoActiveQuery(deqp::Context& context, 834e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, const char* name) 835e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryErrorBase(context, api, name, 836e5c31af7Sopenharmony_ci "Verifies whether an INVALID_OPERATION error is properly generated " 837e5c31af7Sopenharmony_ci "if EndQuery[Indexed] is called with a target " 838e5c31af7Sopenharmony_ci "(and index) for which there isn't a currently active query.") 839e5c31af7Sopenharmony_ci , m_active_stream_overflow_query(0) 840e5c31af7Sopenharmony_ci , m_active_query_stream_index(0) 841e5c31af7Sopenharmony_ci { 842e5c31af7Sopenharmony_ci } 843e5c31af7Sopenharmony_ci 844e5c31af7Sopenharmony_ci /* Test case init. */ 845e5c31af7Sopenharmony_ci virtual void init() 846e5c31af7Sopenharmony_ci { 847e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::init(); 848e5c31af7Sopenharmony_ci 849e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 850e5c31af7Sopenharmony_ci 851e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 852e5c31af7Sopenharmony_ci { 853e5c31af7Sopenharmony_ci gl.genQueries(1, &m_active_stream_overflow_query); 854e5c31af7Sopenharmony_ci m_active_query_stream_index = 2; 855e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index, 856e5c31af7Sopenharmony_ci m_active_stream_overflow_query); 857e5c31af7Sopenharmony_ci } 858e5c31af7Sopenharmony_ci } 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_ci /* Test case deinit */ 861e5c31af7Sopenharmony_ci virtual void deinit() 862e5c31af7Sopenharmony_ci { 863e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 864e5c31af7Sopenharmony_ci 865e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 866e5c31af7Sopenharmony_ci { 867e5c31af7Sopenharmony_ci gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index); 868e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_active_stream_overflow_query); 869e5c31af7Sopenharmony_ci } 870e5c31af7Sopenharmony_ci 871e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryErrorBase::deinit(); 872e5c31af7Sopenharmony_ci } 873e5c31af7Sopenharmony_ci 874e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 875e5c31af7Sopenharmony_ci IterateResult iterate() 876e5c31af7Sopenharmony_ci { 877e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci startTest("EndQuery[Indexed] must generate INVALID_OPERATION if <target> is " 880e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_OVERFLOW and there is no query active " 881e5c31af7Sopenharmony_ci "for TRANSFORM_FEEDBACK_OVERFLOW."); 882e5c31af7Sopenharmony_ci 883e5c31af7Sopenharmony_ci gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW); 884e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 885e5c31af7Sopenharmony_ci gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0); 886e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 887e5c31af7Sopenharmony_ci 888e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 889e5c31af7Sopenharmony_ci { 890e5c31af7Sopenharmony_ci startTest("EndQuery[Indexed] must generate INVALID_OPERATION if <target> is " 891e5c31af7Sopenharmony_ci "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and there is no query active " 892e5c31af7Sopenharmony_ci "for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the given index."); 893e5c31af7Sopenharmony_ci 894e5c31af7Sopenharmony_ci for (GLuint i = 0; i < getMaxVertexStreams(); ++i) 895e5c31af7Sopenharmony_ci { 896e5c31af7Sopenharmony_ci if (i != m_active_query_stream_index) 897e5c31af7Sopenharmony_ci { 898e5c31af7Sopenharmony_ci gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i); 899e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 900e5c31af7Sopenharmony_ci 901e5c31af7Sopenharmony_ci if (i == 0) 902e5c31af7Sopenharmony_ci { 903e5c31af7Sopenharmony_ci gl.endQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW); 904e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION); 905e5c31af7Sopenharmony_ci } 906e5c31af7Sopenharmony_ci } 907e5c31af7Sopenharmony_ci } 908e5c31af7Sopenharmony_ci } 909e5c31af7Sopenharmony_ci 910e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 911e5c31af7Sopenharmony_ci 912e5c31af7Sopenharmony_ci return STOP; 913e5c31af7Sopenharmony_ci } 914e5c31af7Sopenharmony_ci 915e5c31af7Sopenharmony_ciprotected: 916e5c31af7Sopenharmony_ci GLuint m_active_stream_overflow_query; 917e5c31af7Sopenharmony_ci GLuint m_active_query_stream_index; 918e5c31af7Sopenharmony_ci}; 919e5c31af7Sopenharmony_ci 920e5c31af7Sopenharmony_ci/* 921e5c31af7Sopenharmony_ci Base class of all functionality tests. Helps enforce the following requirements: 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci * Ensuring that QUERY_COUNTER_BITS is at least one for the TRANSFORM_FEEDBACK_OVERFLOW query 924e5c31af7Sopenharmony_ci target before running any test that uses such a query's result. 925e5c31af7Sopenharmony_ci 926e5c31af7Sopenharmony_ci * Ensuring that GL 4.0 or ARB_transform_feedback3 is supported and QUERY_COUNTER_BITS is at least 927e5c31af7Sopenharmony_ci one for the TRANSFORM_FEEDBACK_STREAM_OVERFLOW query target before running any test that 928e5c31af7Sopenharmony_ci uses such a query's result. 929e5c31af7Sopenharmony_ci */ 930e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryFunctionalBase : public TransformFeedbackOverflowQueryBaseTest 931e5c31af7Sopenharmony_ci{ 932e5c31af7Sopenharmony_ciprotected: 933e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryFunctionalBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 934e5c31af7Sopenharmony_ci const char* name, const char* description) 935e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryBaseTest(context, api, name, description) 936e5c31af7Sopenharmony_ci , m_overflow_query(0) 937e5c31af7Sopenharmony_ci , m_stream_overflow_query(NULL) 938e5c31af7Sopenharmony_ci , m_query_buffer(0) 939e5c31af7Sopenharmony_ci , m_tf_buffer_count(0) 940e5c31af7Sopenharmony_ci , m_tf_buffer(NULL) 941e5c31af7Sopenharmony_ci , m_vao(0) 942e5c31af7Sopenharmony_ci , m_program(0) 943e5c31af7Sopenharmony_ci , m_checker_program(NULL) 944e5c31af7Sopenharmony_ci { 945e5c31af7Sopenharmony_ci } 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_ci /* Tells whether functional tests using TRANSFORM_FEEDBACK_OVERFLOW are runnable */ 948e5c31af7Sopenharmony_ci bool canTestOverflow() 949e5c31af7Sopenharmony_ci { 950e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 951e5c31af7Sopenharmony_ci GLint counterBits; 952e5c31af7Sopenharmony_ci 953e5c31af7Sopenharmony_ci gl.getQueryiv(GL_TRANSFORM_FEEDBACK_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits); 954e5c31af7Sopenharmony_ci 955e5c31af7Sopenharmony_ci return counterBits > 0; 956e5c31af7Sopenharmony_ci } 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ci /* Tells whether functional tests using TRANSFORM_FEEDBACK_STREAM_OVERFLOW are runnable */ 959e5c31af7Sopenharmony_ci bool canTestStreamOverflow() 960e5c31af7Sopenharmony_ci { 961e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 962e5c31af7Sopenharmony_ci { 963e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 964e5c31af7Sopenharmony_ci GLint counterBits; 965e5c31af7Sopenharmony_ci 966e5c31af7Sopenharmony_ci gl.getQueryiv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits); 967e5c31af7Sopenharmony_ci 968e5c31af7Sopenharmony_ci return counterBits > 0; 969e5c31af7Sopenharmony_ci } 970e5c31af7Sopenharmony_ci else 971e5c31af7Sopenharmony_ci { 972e5c31af7Sopenharmony_ci return false; 973e5c31af7Sopenharmony_ci } 974e5c31af7Sopenharmony_ci } 975e5c31af7Sopenharmony_ci 976e5c31af7Sopenharmony_ci /* Minimal vertex shader. */ 977e5c31af7Sopenharmony_ci const char* minimalVsh() 978e5c31af7Sopenharmony_ci { 979e5c31af7Sopenharmony_ci return "#version 150 core\n" 980e5c31af7Sopenharmony_ci "void main() {\n" 981e5c31af7Sopenharmony_ci " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n" 982e5c31af7Sopenharmony_ci "}\n"; 983e5c31af7Sopenharmony_ci } 984e5c31af7Sopenharmony_ci 985e5c31af7Sopenharmony_ci /* Minimal fragment shader */ 986e5c31af7Sopenharmony_ci const char* minimalFsh() 987e5c31af7Sopenharmony_ci { 988e5c31af7Sopenharmony_ci return "#version 150 core\n" 989e5c31af7Sopenharmony_ci "void main() {}\n"; 990e5c31af7Sopenharmony_ci } 991e5c31af7Sopenharmony_ci 992e5c31af7Sopenharmony_ci /* Functional test init. Creates necessary query objects. */ 993e5c31af7Sopenharmony_ci virtual void init() 994e5c31af7Sopenharmony_ci { 995e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryBaseTest::init(); 996e5c31af7Sopenharmony_ci 997e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci if (canTestOverflow()) 1000e5c31af7Sopenharmony_ci { 1001e5c31af7Sopenharmony_ci // Setup vertex array 1002e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao); 1003e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao); 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_ci // Setup queries 1006e5c31af7Sopenharmony_ci gl.genQueries(1, &m_overflow_query); 1007e5c31af7Sopenharmony_ci 1008e5c31af7Sopenharmony_ci if (canTestStreamOverflow()) 1009e5c31af7Sopenharmony_ci { 1010e5c31af7Sopenharmony_ci m_stream_overflow_query = new GLuint[getMaxVertexStreams()]; 1011e5c31af7Sopenharmony_ci 1012e5c31af7Sopenharmony_ci gl.genQueries(getMaxVertexStreams(), m_stream_overflow_query); 1013e5c31af7Sopenharmony_ci } 1014e5c31af7Sopenharmony_ci 1015e5c31af7Sopenharmony_ci // Setup checker program 1016e5c31af7Sopenharmony_ci m_checker_program = 1017e5c31af7Sopenharmony_ci new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(minimalVsh(), minimalFsh())); 1018e5c31af7Sopenharmony_ci if (!m_checker_program->isOk()) 1019e5c31af7Sopenharmony_ci { 1020e5c31af7Sopenharmony_ci TCU_FAIL("Checker program compilation failed"); 1021e5c31af7Sopenharmony_ci } 1022e5c31af7Sopenharmony_ci 1023e5c31af7Sopenharmony_ci // Setup transform feedback shader and buffers 1024e5c31af7Sopenharmony_ci buildTransformFeedbackProgram(); 1025e5c31af7Sopenharmony_ci setupTransformFeedbackBuffers(); 1026e5c31af7Sopenharmony_ci } 1027e5c31af7Sopenharmony_ci else 1028e5c31af7Sopenharmony_ci { 1029e5c31af7Sopenharmony_ci throw tcu::NotSupportedError( 1030e5c31af7Sopenharmony_ci "QUERY_COUNTER_BITS for TRANSFORM_FEEDBACK_OVERFLOW queries is zero, skipping test"); 1031e5c31af7Sopenharmony_ci } 1032e5c31af7Sopenharmony_ci } 1033e5c31af7Sopenharmony_ci 1034e5c31af7Sopenharmony_ci /* Functional test deinit. Deletes created query objects */ 1035e5c31af7Sopenharmony_ci virtual void deinit() 1036e5c31af7Sopenharmony_ci { 1037e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1038e5c31af7Sopenharmony_ci 1039e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao); 1040e5c31af7Sopenharmony_ci 1041e5c31af7Sopenharmony_ci gl.deleteQueries(1, &m_overflow_query); 1042e5c31af7Sopenharmony_ci 1043e5c31af7Sopenharmony_ci if (canTestStreamOverflow()) 1044e5c31af7Sopenharmony_ci { 1045e5c31af7Sopenharmony_ci if (m_stream_overflow_query != NULL) 1046e5c31af7Sopenharmony_ci { 1047e5c31af7Sopenharmony_ci gl.deleteQueries(getMaxVertexStreams(), m_stream_overflow_query); 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci delete[] m_stream_overflow_query; 1050e5c31af7Sopenharmony_ci } 1051e5c31af7Sopenharmony_ci } 1052e5c31af7Sopenharmony_ci 1053e5c31af7Sopenharmony_ci if (m_checker_program != NULL) 1054e5c31af7Sopenharmony_ci { 1055e5c31af7Sopenharmony_ci delete m_checker_program; 1056e5c31af7Sopenharmony_ci } 1057e5c31af7Sopenharmony_ci 1058e5c31af7Sopenharmony_ci gl.useProgram(0); 1059e5c31af7Sopenharmony_ci gl.deleteProgram(m_program); 1060e5c31af7Sopenharmony_ci 1061e5c31af7Sopenharmony_ci if (m_tf_buffer != NULL) 1062e5c31af7Sopenharmony_ci { 1063e5c31af7Sopenharmony_ci gl.deleteBuffers(m_tf_buffer_count, m_tf_buffer); 1064e5c31af7Sopenharmony_ci 1065e5c31af7Sopenharmony_ci delete[] m_tf_buffer; 1066e5c31af7Sopenharmony_ci } 1067e5c31af7Sopenharmony_ci 1068e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryBaseTest::deinit(); 1069e5c31af7Sopenharmony_ci } 1070e5c31af7Sopenharmony_ci 1071e5c31af7Sopenharmony_ci /* 1072e5c31af7Sopenharmony_ci Basic Checking Mechanism 1073e5c31af7Sopenharmony_ci 1074e5c31af7Sopenharmony_ci * Call BeginConditionalRender with mode QUERY_WAIT and with the given 1075e5c31af7Sopenharmony_ci query object as parameters. Draw something, then call EndConditional- 1076e5c31af7Sopenharmony_ci Render. If the expected result for the query is FALSE, expect 1077e5c31af7Sopenharmony_ci conditional render to discard the previous draw command. 1078e5c31af7Sopenharmony_ci 1079e5c31af7Sopenharmony_ci * If GL 4.5 or ARB_conditional_render_inverted is supported, call Begin- 1080e5c31af7Sopenharmony_ci ConditionalRender with mode QUERY_WAIT_INVERTED and with the given query 1081e5c31af7Sopenharmony_ci object as parameters. Draw something, then call EndConditionalRender. If 1082e5c31af7Sopenharmony_ci the expected result for the query is TRUE, expect conditional render to 1083e5c31af7Sopenharmony_ci discard the previous draw command. 1084e5c31af7Sopenharmony_ci 1085e5c31af7Sopenharmony_ci * Finally, check using GetQueryObjectiv with QUERY_RESULT that the result 1086e5c31af7Sopenharmony_ci of the query matches the expected result. 1087e5c31af7Sopenharmony_ci 1088e5c31af7Sopenharmony_ci * If GL 4.4 or ARB_query_buffer_object is supported then check the result 1089e5c31af7Sopenharmony_ci of the query against the expected result also by having a query buffer 1090e5c31af7Sopenharmony_ci bound at the time of calling GetQueryObjectiv. 1091e5c31af7Sopenharmony_ci */ 1092e5c31af7Sopenharmony_ci bool verifyQueryResult(GLuint query, GLboolean expected) 1093e5c31af7Sopenharmony_ci { 1094e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1095e5c31af7Sopenharmony_ci bool result = true; 1096e5c31af7Sopenharmony_ci GLuint actual; 1097e5c31af7Sopenharmony_ci 1098e5c31af7Sopenharmony_ci GLuint current_program = m_context.getContextInfo().getInt(GL_CURRENT_PROGRAM); 1099e5c31af7Sopenharmony_ci GLuint checker_query, check_result; 1100e5c31af7Sopenharmony_ci 1101e5c31af7Sopenharmony_ci // We'll use a PRIMITIVES_GENERATED query to test whether conditional 1102e5c31af7Sopenharmony_ci // rendering actually executed the draw command or not. If the draw command 1103e5c31af7Sopenharmony_ci // was discarded then the PRIMITIVES_GENERATED query should have a result 1104e5c31af7Sopenharmony_ci // of zero. 1105e5c31af7Sopenharmony_ci gl.genQueries(1, &checker_query); 1106e5c31af7Sopenharmony_ci 1107e5c31af7Sopenharmony_ci gl.useProgram(m_checker_program->getProgram()); 1108e5c31af7Sopenharmony_ci 1109e5c31af7Sopenharmony_ci // Verify that conditional render discards the rendering if the expected 1110e5c31af7Sopenharmony_ci // result is FALSE and renders otherwise. 1111e5c31af7Sopenharmony_ci gl.beginConditionalRender(query, GL_QUERY_WAIT); 1112e5c31af7Sopenharmony_ci gl.beginQuery(GL_PRIMITIVES_GENERATED, checker_query); 1113e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, 1); 1114e5c31af7Sopenharmony_ci gl.endQuery(GL_PRIMITIVES_GENERATED); 1115e5c31af7Sopenharmony_ci gl.endConditionalRender(); 1116e5c31af7Sopenharmony_ci gl.getQueryObjectuiv(checker_query, GL_QUERY_RESULT, &check_result); 1117e5c31af7Sopenharmony_ci if (check_result != (GLuint)expected) 1118e5c31af7Sopenharmony_ci { 1119e5c31af7Sopenharmony_ci result = false; 1120e5c31af7Sopenharmony_ci } 1121e5c31af7Sopenharmony_ci 1122e5c31af7Sopenharmony_ci // Verify that an inverted conditional render discards the rendering if 1123e5c31af7Sopenharmony_ci // the expected result is TRUE and renders otherwise. 1124e5c31af7Sopenharmony_ci if (supportsConditionalRenderInverted()) 1125e5c31af7Sopenharmony_ci { 1126e5c31af7Sopenharmony_ci gl.beginConditionalRender(query, GL_QUERY_WAIT_INVERTED); 1127e5c31af7Sopenharmony_ci gl.beginQuery(GL_PRIMITIVES_GENERATED, checker_query); 1128e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, 1); 1129e5c31af7Sopenharmony_ci gl.endQuery(GL_PRIMITIVES_GENERATED); 1130e5c31af7Sopenharmony_ci gl.endConditionalRender(); 1131e5c31af7Sopenharmony_ci gl.getQueryObjectuiv(checker_query, GL_QUERY_RESULT, &check_result); 1132e5c31af7Sopenharmony_ci if (check_result == (GLuint)expected) 1133e5c31af7Sopenharmony_ci { 1134e5c31af7Sopenharmony_ci result = false; 1135e5c31af7Sopenharmony_ci } 1136e5c31af7Sopenharmony_ci } 1137e5c31af7Sopenharmony_ci 1138e5c31af7Sopenharmony_ci gl.useProgram(current_program); 1139e5c31af7Sopenharmony_ci 1140e5c31af7Sopenharmony_ci // Verify that the result of the query matches the expected result. 1141e5c31af7Sopenharmony_ci gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &actual); 1142e5c31af7Sopenharmony_ci if ((GLboolean)actual != expected) 1143e5c31af7Sopenharmony_ci { 1144e5c31af7Sopenharmony_ci result = false; 1145e5c31af7Sopenharmony_ci } 1146e5c31af7Sopenharmony_ci 1147e5c31af7Sopenharmony_ci // Verify that the result of the query matches the expected result even 1148e5c31af7Sopenharmony_ci // when using a query buffer. 1149e5c31af7Sopenharmony_ci if (supportsQueryBufferObject()) 1150e5c31af7Sopenharmony_ci { 1151e5c31af7Sopenharmony_ci const GLuint initValue = 0xDEADBEEF; 1152e5c31af7Sopenharmony_ci 1153e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_query_buffer); 1154e5c31af7Sopenharmony_ci gl.bindBuffer(GL_QUERY_BUFFER, m_query_buffer); 1155e5c31af7Sopenharmony_ci gl.bufferData(GL_QUERY_BUFFER, sizeof(initValue), &initValue, GL_STREAM_READ); 1156e5c31af7Sopenharmony_ci gl.getQueryObjectuiv(query, GL_QUERY_RESULT, NULL); 1157e5c31af7Sopenharmony_ci gl.getBufferSubData(GL_QUERY_BUFFER, 0, sizeof(actual), &actual); 1158e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_query_buffer); 1159e5c31af7Sopenharmony_ci 1160e5c31af7Sopenharmony_ci if ((GLboolean)actual != expected) 1161e5c31af7Sopenharmony_ci { 1162e5c31af7Sopenharmony_ci result = false; 1163e5c31af7Sopenharmony_ci } 1164e5c31af7Sopenharmony_ci } 1165e5c31af7Sopenharmony_ci 1166e5c31af7Sopenharmony_ci gl.deleteQueries(1, &checker_query); 1167e5c31af7Sopenharmony_ci 1168e5c31af7Sopenharmony_ci return result; 1169e5c31af7Sopenharmony_ci } 1170e5c31af7Sopenharmony_ci 1171e5c31af7Sopenharmony_ci /* Verifies the result of all queries. There can only be up to 5 non-FALSE result queries as none of 1172e5c31af7Sopenharmony_ci the tests use more than 4 vertex streams so the rest is assumed to always have a FALSE result. */ 1173e5c31af7Sopenharmony_ci void verifyQueryResults(GLboolean any, GLboolean stream0, GLboolean stream1, GLboolean stream2 = GL_FALSE, 1174e5c31af7Sopenharmony_ci GLboolean stream3 = GL_FALSE) 1175e5c31af7Sopenharmony_ci { 1176e5c31af7Sopenharmony_ci bool result = true; 1177e5c31af7Sopenharmony_ci 1178e5c31af7Sopenharmony_ci // Verify the result of the TRANSFORM_FEEDBACK_OVERFLOW query. 1179e5c31af7Sopenharmony_ci result &= verifyQueryResult(m_overflow_query, any); 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 1182e5c31af7Sopenharmony_ci { 1183e5c31af7Sopenharmony_ci // Verify the result of the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries 1184e5c31af7Sopenharmony_ci // corresponding to the first 4 vertex streams. 1185e5c31af7Sopenharmony_ci result &= verifyQueryResult(m_stream_overflow_query[0], stream0); 1186e5c31af7Sopenharmony_ci result &= verifyQueryResult(m_stream_overflow_query[1], stream1); 1187e5c31af7Sopenharmony_ci result &= verifyQueryResult(m_stream_overflow_query[2], stream2); 1188e5c31af7Sopenharmony_ci result &= verifyQueryResult(m_stream_overflow_query[3], stream3); 1189e5c31af7Sopenharmony_ci 1190e5c31af7Sopenharmony_ci // Expect the rest of the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries 1191e5c31af7Sopenharmony_ci // to have a FALSE result. 1192e5c31af7Sopenharmony_ci for (GLuint i = 4; i < getMaxVertexStreams(); ++i) 1193e5c31af7Sopenharmony_ci { 1194e5c31af7Sopenharmony_ci result &= verifyQueryResult(m_stream_overflow_query[i], GL_FALSE); 1195e5c31af7Sopenharmony_ci } 1196e5c31af7Sopenharmony_ci } 1197e5c31af7Sopenharmony_ci 1198e5c31af7Sopenharmony_ci if (!result) 1199e5c31af7Sopenharmony_ci { 1200e5c31af7Sopenharmony_ci TCU_FAIL("Failed to validate the results of the queries"); 1201e5c31af7Sopenharmony_ci } 1202e5c31af7Sopenharmony_ci } 1203e5c31af7Sopenharmony_ci 1204e5c31af7Sopenharmony_ci /* Single stream version of verifyQueryResults */ 1205e5c31af7Sopenharmony_ci void verifyQueryResults(GLboolean result) 1206e5c31af7Sopenharmony_ci { 1207e5c31af7Sopenharmony_ci verifyQueryResults(result, result, GL_FALSE, GL_FALSE, GL_FALSE); 1208e5c31af7Sopenharmony_ci } 1209e5c31af7Sopenharmony_ci 1210e5c31af7Sopenharmony_ci /* Compiles and links transform feedback program. */ 1211e5c31af7Sopenharmony_ci void buildTransformFeedbackProgram() 1212e5c31af7Sopenharmony_ci { 1213e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1214e5c31af7Sopenharmony_ci 1215e5c31af7Sopenharmony_ci GLint status; 1216e5c31af7Sopenharmony_ci 1217e5c31af7Sopenharmony_ci m_program = gl.createProgram(); 1218e5c31af7Sopenharmony_ci 1219e5c31af7Sopenharmony_ci const char* vsSource = transformFeedbackVertexShader(); 1220e5c31af7Sopenharmony_ci 1221e5c31af7Sopenharmony_ci GLuint vShader = gl.createShader(GL_VERTEX_SHADER); 1222e5c31af7Sopenharmony_ci gl.shaderSource(vShader, 1, (const char**)&vsSource, NULL); 1223e5c31af7Sopenharmony_ci gl.compileShader(vShader); 1224e5c31af7Sopenharmony_ci gl.getShaderiv(vShader, GL_COMPILE_STATUS, &status); 1225e5c31af7Sopenharmony_ci if (status == GL_FALSE) 1226e5c31af7Sopenharmony_ci { 1227e5c31af7Sopenharmony_ci GLint infoLogLength = 0; 1228e5c31af7Sopenharmony_ci gl.getShaderiv(vShader, GL_INFO_LOG_LENGTH, &infoLogLength); 1229e5c31af7Sopenharmony_ci 1230e5c31af7Sopenharmony_ci std::vector<char> infoLogBuf(infoLogLength + 1); 1231e5c31af7Sopenharmony_ci gl.getShaderInfoLog(vShader, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]); 1232e5c31af7Sopenharmony_ci 1233e5c31af7Sopenharmony_ci std::string infoLog = &infoLogBuf[0]; 1234e5c31af7Sopenharmony_ci m_testCtx.getLog().writeShader(QP_SHADER_TYPE_VERTEX, vsSource, false, infoLog.c_str()); 1235e5c31af7Sopenharmony_ci 1236e5c31af7Sopenharmony_ci gl.deleteShader(vShader); 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile transform feedback vertex shader"); 1239e5c31af7Sopenharmony_ci } 1240e5c31af7Sopenharmony_ci gl.attachShader(m_program, vShader); 1241e5c31af7Sopenharmony_ci gl.deleteShader(vShader); 1242e5c31af7Sopenharmony_ci 1243e5c31af7Sopenharmony_ci const char* gsSource = transformFeedbackGeometryShader(); 1244e5c31af7Sopenharmony_ci 1245e5c31af7Sopenharmony_ci if (gsSource) 1246e5c31af7Sopenharmony_ci { 1247e5c31af7Sopenharmony_ci GLuint gShader = gl.createShader(GL_GEOMETRY_SHADER); 1248e5c31af7Sopenharmony_ci gl.shaderSource(gShader, 1, (const char**)&gsSource, NULL); 1249e5c31af7Sopenharmony_ci gl.compileShader(gShader); 1250e5c31af7Sopenharmony_ci gl.getShaderiv(gShader, GL_COMPILE_STATUS, &status); 1251e5c31af7Sopenharmony_ci if (status == GL_FALSE) 1252e5c31af7Sopenharmony_ci { 1253e5c31af7Sopenharmony_ci GLint infoLogLength = 0; 1254e5c31af7Sopenharmony_ci gl.getShaderiv(gShader, GL_INFO_LOG_LENGTH, &infoLogLength); 1255e5c31af7Sopenharmony_ci 1256e5c31af7Sopenharmony_ci std::vector<char> infoLogBuf(infoLogLength + 1); 1257e5c31af7Sopenharmony_ci gl.getShaderInfoLog(gShader, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]); 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci std::string infoLog = &infoLogBuf[0]; 1260e5c31af7Sopenharmony_ci m_testCtx.getLog().writeShader(QP_SHADER_TYPE_GEOMETRY, gsSource, false, infoLog.c_str()); 1261e5c31af7Sopenharmony_ci 1262e5c31af7Sopenharmony_ci gl.deleteShader(gShader); 1263e5c31af7Sopenharmony_ci 1264e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile transform feedback geometry shader"); 1265e5c31af7Sopenharmony_ci } 1266e5c31af7Sopenharmony_ci gl.attachShader(m_program, gShader); 1267e5c31af7Sopenharmony_ci gl.deleteShader(gShader); 1268e5c31af7Sopenharmony_ci } 1269e5c31af7Sopenharmony_ci 1270e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(m_program, varyingsCount(), varyings(), bufferMode()); 1271e5c31af7Sopenharmony_ci gl.linkProgram(m_program); 1272e5c31af7Sopenharmony_ci gl.getProgramiv(m_program, GL_LINK_STATUS, &status); 1273e5c31af7Sopenharmony_ci if (status == GL_FALSE) 1274e5c31af7Sopenharmony_ci { 1275e5c31af7Sopenharmony_ci GLint infoLogLength = 0; 1276e5c31af7Sopenharmony_ci gl.getProgramiv(m_program, GL_INFO_LOG_LENGTH, &infoLogLength); 1277e5c31af7Sopenharmony_ci 1278e5c31af7Sopenharmony_ci std::vector<char> infoLogBuf(infoLogLength + 1); 1279e5c31af7Sopenharmony_ci gl.getProgramInfoLog(m_program, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]); 1280e5c31af7Sopenharmony_ci 1281e5c31af7Sopenharmony_ci std::string infoLog = &infoLogBuf[0]; 1282e5c31af7Sopenharmony_ci m_testCtx.getLog().writeShader(QP_SHADER_TYPE_VERTEX, vsSource, true, infoLog.c_str()); 1283e5c31af7Sopenharmony_ci 1284e5c31af7Sopenharmony_ci TCU_FAIL("Failed to link transform feedback program"); 1285e5c31af7Sopenharmony_ci } 1286e5c31af7Sopenharmony_ci 1287e5c31af7Sopenharmony_ci gl.useProgram(m_program); 1288e5c31af7Sopenharmony_ci } 1289e5c31af7Sopenharmony_ci 1290e5c31af7Sopenharmony_ci /* Generates a number of transform feedback buffers and binds them. */ 1291e5c31af7Sopenharmony_ci void setupTransformFeedbackBuffers() 1292e5c31af7Sopenharmony_ci { 1293e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1294e5c31af7Sopenharmony_ci 1295e5c31af7Sopenharmony_ci m_tf_buffer_count = bufferCount(); 1296e5c31af7Sopenharmony_ci 1297e5c31af7Sopenharmony_ci m_tf_buffer = new GLuint[m_tf_buffer_count]; 1298e5c31af7Sopenharmony_ci 1299e5c31af7Sopenharmony_ci gl.genBuffers(m_tf_buffer_count, m_tf_buffer); 1300e5c31af7Sopenharmony_ci 1301e5c31af7Sopenharmony_ci for (GLint i = 0; i < m_tf_buffer_count; ++i) 1302e5c31af7Sopenharmony_ci { 1303e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_tf_buffer[i]); 1304e5c31af7Sopenharmony_ci gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferSize(i), NULL, GL_DYNAMIC_COPY); 1305e5c31af7Sopenharmony_ci } 1306e5c31af7Sopenharmony_ci } 1307e5c31af7Sopenharmony_ci 1308e5c31af7Sopenharmony_ci /* Starts all overflow queries. */ 1309e5c31af7Sopenharmony_ci void beginQueries() 1310e5c31af7Sopenharmony_ci { 1311e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1312e5c31af7Sopenharmony_ci 1313e5c31af7Sopenharmony_ci gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query); 1314e5c31af7Sopenharmony_ci 1315e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 1316e5c31af7Sopenharmony_ci { 1317e5c31af7Sopenharmony_ci for (GLuint i = 0; i < getMaxVertexStreams(); ++i) 1318e5c31af7Sopenharmony_ci { 1319e5c31af7Sopenharmony_ci gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_stream_overflow_query[i]); 1320e5c31af7Sopenharmony_ci } 1321e5c31af7Sopenharmony_ci } 1322e5c31af7Sopenharmony_ci } 1323e5c31af7Sopenharmony_ci 1324e5c31af7Sopenharmony_ci /* Stops all overflow queries. */ 1325e5c31af7Sopenharmony_ci void endQueries() 1326e5c31af7Sopenharmony_ci { 1327e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1328e5c31af7Sopenharmony_ci 1329e5c31af7Sopenharmony_ci gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW); 1330e5c31af7Sopenharmony_ci 1331e5c31af7Sopenharmony_ci if (supportsTransformFeedback3()) 1332e5c31af7Sopenharmony_ci { 1333e5c31af7Sopenharmony_ci for (GLuint i = 0; i < getMaxVertexStreams(); ++i) 1334e5c31af7Sopenharmony_ci { 1335e5c31af7Sopenharmony_ci gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i); 1336e5c31af7Sopenharmony_ci } 1337e5c31af7Sopenharmony_ci } 1338e5c31af7Sopenharmony_ci } 1339e5c31af7Sopenharmony_ci 1340e5c31af7Sopenharmony_ci /* Draws a set of points to vertex stream #0 while having the overflow queries active. */ 1341e5c31af7Sopenharmony_ci void drawPoints(GLsizei count) 1342e5c31af7Sopenharmony_ci { 1343e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1344e5c31af7Sopenharmony_ci 1345e5c31af7Sopenharmony_ci beginQueries(); 1346e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, count); 1347e5c31af7Sopenharmony_ci endQueries(); 1348e5c31af7Sopenharmony_ci } 1349e5c31af7Sopenharmony_ci 1350e5c31af7Sopenharmony_ci /* Draws a set of triangles to vertex stream #0 while having the overflow queries active. */ 1351e5c31af7Sopenharmony_ci void drawTriangles(GLsizei count) 1352e5c31af7Sopenharmony_ci { 1353e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1354e5c31af7Sopenharmony_ci 1355e5c31af7Sopenharmony_ci beginQueries(); 1356e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLES, 0, count * 3); 1357e5c31af7Sopenharmony_ci endQueries(); 1358e5c31af7Sopenharmony_ci } 1359e5c31af7Sopenharmony_ci 1360e5c31af7Sopenharmony_ci /* Vertex shader to use for transform feedback. */ 1361e5c31af7Sopenharmony_ci virtual const char* transformFeedbackVertexShader() = 0; 1362e5c31af7Sopenharmony_ci 1363e5c31af7Sopenharmony_ci /* Geometry shader to use for transform feedback. */ 1364e5c31af7Sopenharmony_ci virtual const char* transformFeedbackGeometryShader() = 0; 1365e5c31af7Sopenharmony_ci 1366e5c31af7Sopenharmony_ci /* Returns the number of transform feedback varyings. */ 1367e5c31af7Sopenharmony_ci virtual GLsizei varyingsCount() = 0; 1368e5c31af7Sopenharmony_ci 1369e5c31af7Sopenharmony_ci /* Returns the array of transform feedback varying names. */ 1370e5c31af7Sopenharmony_ci virtual const char** varyings() = 0; 1371e5c31af7Sopenharmony_ci 1372e5c31af7Sopenharmony_ci /* Returns the transform feedback buffer mode. */ 1373e5c31af7Sopenharmony_ci virtual GLenum bufferMode() = 0; 1374e5c31af7Sopenharmony_ci 1375e5c31af7Sopenharmony_ci /* Returns the number of transform feedback buffers. */ 1376e5c31af7Sopenharmony_ci virtual GLsizei bufferCount() = 0; 1377e5c31af7Sopenharmony_ci 1378e5c31af7Sopenharmony_ci /* Returns the size of the specified transform feedback buffer. */ 1379e5c31af7Sopenharmony_ci virtual GLsizei bufferSize(GLint index) = 0; 1380e5c31af7Sopenharmony_ci 1381e5c31af7Sopenharmony_ciprotected: 1382e5c31af7Sopenharmony_ci GLuint m_overflow_query; 1383e5c31af7Sopenharmony_ci GLuint* m_stream_overflow_query; 1384e5c31af7Sopenharmony_ci GLuint m_query_buffer; 1385e5c31af7Sopenharmony_ci GLsizei m_tf_buffer_count; 1386e5c31af7Sopenharmony_ci GLuint* m_tf_buffer; 1387e5c31af7Sopenharmony_ci GLuint m_vao; 1388e5c31af7Sopenharmony_ci GLuint m_program; 1389e5c31af7Sopenharmony_ci glu::ShaderProgram* m_checker_program; 1390e5c31af7Sopenharmony_ci}; 1391e5c31af7Sopenharmony_ci 1392e5c31af7Sopenharmony_ci/* 1393e5c31af7Sopenharmony_ci Base class for all single stream test cases. 1394e5c31af7Sopenharmony_ci */ 1395e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQuerySingleStreamBase : public TransformFeedbackOverflowQueryFunctionalBase 1396e5c31af7Sopenharmony_ci{ 1397e5c31af7Sopenharmony_ciprotected: 1398e5c31af7Sopenharmony_ci TransformFeedbackOverflowQuerySingleStreamBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api, 1399e5c31af7Sopenharmony_ci const char* name, const char* description) 1400e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryFunctionalBase(context, api, name, description) 1401e5c31af7Sopenharmony_ci { 1402e5c31af7Sopenharmony_ci } 1403e5c31af7Sopenharmony_ci 1404e5c31af7Sopenharmony_ci /* Vertex shader to use for transform feedback. */ 1405e5c31af7Sopenharmony_ci virtual const char* transformFeedbackVertexShader() 1406e5c31af7Sopenharmony_ci { 1407e5c31af7Sopenharmony_ci return "#version 150 core\n" 1408e5c31af7Sopenharmony_ci "out float output1;\n" 1409e5c31af7Sopenharmony_ci "out float output2;\n" 1410e5c31af7Sopenharmony_ci "out float output3;\n" 1411e5c31af7Sopenharmony_ci "out float output4;\n" 1412e5c31af7Sopenharmony_ci "void main() {\n" 1413e5c31af7Sopenharmony_ci " output1 = 1.0;\n" 1414e5c31af7Sopenharmony_ci " output2 = 2.0;\n" 1415e5c31af7Sopenharmony_ci " output3 = 3.0;\n" 1416e5c31af7Sopenharmony_ci " output4 = 4.0;\n" 1417e5c31af7Sopenharmony_ci "}"; 1418e5c31af7Sopenharmony_ci } 1419e5c31af7Sopenharmony_ci 1420e5c31af7Sopenharmony_ci /* No geometry shader for single stream test cases. */ 1421e5c31af7Sopenharmony_ci virtual const char* transformFeedbackGeometryShader() 1422e5c31af7Sopenharmony_ci { 1423e5c31af7Sopenharmony_ci return NULL; 1424e5c31af7Sopenharmony_ci } 1425e5c31af7Sopenharmony_ci 1426e5c31af7Sopenharmony_ci /* There are a total of 4 varyings. */ 1427e5c31af7Sopenharmony_ci virtual GLsizei varyingsCount() 1428e5c31af7Sopenharmony_ci { 1429e5c31af7Sopenharmony_ci return 4; 1430e5c31af7Sopenharmony_ci } 1431e5c31af7Sopenharmony_ci 1432e5c31af7Sopenharmony_ci /* The varying name list contains all outputs in order. */ 1433e5c31af7Sopenharmony_ci virtual const char** varyings() 1434e5c31af7Sopenharmony_ci { 1435e5c31af7Sopenharmony_ci static const char* vars[] = { "output1", "output2", "output3", "output4" }; 1436e5c31af7Sopenharmony_ci return vars; 1437e5c31af7Sopenharmony_ci } 1438e5c31af7Sopenharmony_ci}; 1439e5c31af7Sopenharmony_ci 1440e5c31af7Sopenharmony_ci/* 1441e5c31af7Sopenharmony_ci Test case #1 - Basic single stream, interleaved attributes. 1442e5c31af7Sopenharmony_ci */ 1443e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs 1444e5c31af7Sopenharmony_ci : public TransformFeedbackOverflowQuerySingleStreamBase 1445e5c31af7Sopenharmony_ci{ 1446e5c31af7Sopenharmony_cipublic: 1447e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs(deqp::Context& context, 1448e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, 1449e5c31af7Sopenharmony_ci const char* name) 1450e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQuerySingleStreamBase(context, api, name, 1451e5c31af7Sopenharmony_ci "Basic single stream, interleaved attributes.") 1452e5c31af7Sopenharmony_ci { 1453e5c31af7Sopenharmony_ci } 1454e5c31af7Sopenharmony_ci 1455e5c31af7Sopenharmony_ci /* Use interleaved attributes. */ 1456e5c31af7Sopenharmony_ci virtual GLenum bufferMode() 1457e5c31af7Sopenharmony_ci { 1458e5c31af7Sopenharmony_ci return GL_INTERLEAVED_ATTRIBS; 1459e5c31af7Sopenharmony_ci } 1460e5c31af7Sopenharmony_ci 1461e5c31af7Sopenharmony_ci /* A single transform feedback buffer is enough. */ 1462e5c31af7Sopenharmony_ci virtual GLsizei bufferCount() 1463e5c31af7Sopenharmony_ci { 1464e5c31af7Sopenharmony_ci return 1; 1465e5c31af7Sopenharmony_ci } 1466e5c31af7Sopenharmony_ci 1467e5c31af7Sopenharmony_ci /* The transform feedback buffer should be able to capture exactly 10 vertices. */ 1468e5c31af7Sopenharmony_ci virtual GLsizei bufferSize(GLint index) 1469e5c31af7Sopenharmony_ci { 1470e5c31af7Sopenharmony_ci (void)index; 1471e5c31af7Sopenharmony_ci return static_cast<GLsizei>(10 * sizeof(GLfloat) * varyingsCount()); 1472e5c31af7Sopenharmony_ci } 1473e5c31af7Sopenharmony_ci 1474e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 1475e5c31af7Sopenharmony_ci IterateResult iterate() 1476e5c31af7Sopenharmony_ci { 1477e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1478e5c31af7Sopenharmony_ci 1479e5c31af7Sopenharmony_ci // Call BeginTransformFeedback with mode POINTS. 1480e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 1481e5c31af7Sopenharmony_ci 1482e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 10 1483e5c31af7Sopenharmony_ci // points, then stop the query. 1484e5c31af7Sopenharmony_ci drawPoints(10); 1485e5c31af7Sopenharmony_ci 1486e5c31af7Sopenharmony_ci // Call EndTransformFeedback. 1487e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 1488e5c31af7Sopenharmony_ci 1489e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1490e5c31af7Sopenharmony_ci // query is FALSE. 1491e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1492e5c31af7Sopenharmony_ci 1493e5c31af7Sopenharmony_ci // Repeat the above steps, but this time feed back more than 10 vertices 1494e5c31af7Sopenharmony_ci // and expect the result of the query to be TRUE. 1495e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 1496e5c31af7Sopenharmony_ci drawPoints(11); 1497e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 1498e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE); 1499e5c31af7Sopenharmony_ci 1500e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1501e5c31af7Sopenharmony_ci 1502e5c31af7Sopenharmony_ci return STOP; 1503e5c31af7Sopenharmony_ci } 1504e5c31af7Sopenharmony_ci}; 1505e5c31af7Sopenharmony_ci 1506e5c31af7Sopenharmony_ci/* 1507e5c31af7Sopenharmony_ci Test case #2 - Basic single stream, separate attributes. 1508e5c31af7Sopenharmony_ci */ 1509e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs 1510e5c31af7Sopenharmony_ci : public TransformFeedbackOverflowQuerySingleStreamBase 1511e5c31af7Sopenharmony_ci{ 1512e5c31af7Sopenharmony_cipublic: 1513e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs(deqp::Context& context, 1514e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, 1515e5c31af7Sopenharmony_ci const char* name) 1516e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQuerySingleStreamBase(context, api, name, 1517e5c31af7Sopenharmony_ci "Basic single stream, separate attributes.") 1518e5c31af7Sopenharmony_ci { 1519e5c31af7Sopenharmony_ci } 1520e5c31af7Sopenharmony_ci 1521e5c31af7Sopenharmony_ci /* Use separate attributes. */ 1522e5c31af7Sopenharmony_ci virtual GLenum bufferMode() 1523e5c31af7Sopenharmony_ci { 1524e5c31af7Sopenharmony_ci return GL_SEPARATE_ATTRIBS; 1525e5c31af7Sopenharmony_ci } 1526e5c31af7Sopenharmony_ci 1527e5c31af7Sopenharmony_ci /* We need a separate buffer for each varying. */ 1528e5c31af7Sopenharmony_ci virtual GLsizei bufferCount() 1529e5c31af7Sopenharmony_ci { 1530e5c31af7Sopenharmony_ci return varyingsCount(); 1531e5c31af7Sopenharmony_ci } 1532e5c31af7Sopenharmony_ci 1533e5c31af7Sopenharmony_ci /* One of the transform feedback buffers should be able to capture exactly 12 vertices, 1534e5c31af7Sopenharmony_ci the others should be able to capture at least 15 vertices. */ 1535e5c31af7Sopenharmony_ci virtual GLsizei bufferSize(GLint index) 1536e5c31af7Sopenharmony_ci { 1537e5c31af7Sopenharmony_ci if (index == 1) 1538e5c31af7Sopenharmony_ci { 1539e5c31af7Sopenharmony_ci return 12 * sizeof(GLfloat); 1540e5c31af7Sopenharmony_ci } 1541e5c31af7Sopenharmony_ci else 1542e5c31af7Sopenharmony_ci { 1543e5c31af7Sopenharmony_ci return 15 * sizeof(GLfloat); 1544e5c31af7Sopenharmony_ci } 1545e5c31af7Sopenharmony_ci } 1546e5c31af7Sopenharmony_ci 1547e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 1548e5c31af7Sopenharmony_ci IterateResult iterate() 1549e5c31af7Sopenharmony_ci { 1550e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1551e5c31af7Sopenharmony_ci 1552e5c31af7Sopenharmony_ci // Call BeginTransformFeedback with mode TRIANGLES. 1553e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_TRIANGLES); 1554e5c31af7Sopenharmony_ci 1555e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 4 1556e5c31af7Sopenharmony_ci // triangles, then stop the query. 1557e5c31af7Sopenharmony_ci drawTriangles(4); 1558e5c31af7Sopenharmony_ci 1559e5c31af7Sopenharmony_ci // Call EndTransformFeedback. 1560e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 1561e5c31af7Sopenharmony_ci 1562e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1563e5c31af7Sopenharmony_ci // query is FALSE. 1564e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1565e5c31af7Sopenharmony_ci 1566e5c31af7Sopenharmony_ci // Repeat the above steps, but this time feed back exactly 5 triangles 1567e5c31af7Sopenharmony_ci // and expect the result of the query to be TRUE. 1568e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_TRIANGLES); 1569e5c31af7Sopenharmony_ci drawTriangles(5); 1570e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 1571e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE); 1572e5c31af7Sopenharmony_ci 1573e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1574e5c31af7Sopenharmony_ci 1575e5c31af7Sopenharmony_ci return STOP; 1576e5c31af7Sopenharmony_ci } 1577e5c31af7Sopenharmony_ci}; 1578e5c31af7Sopenharmony_ci 1579e5c31af7Sopenharmony_ci/* 1580e5c31af7Sopenharmony_ci Test case #3 - Advanced single stream, interleaved attributes. 1581e5c31af7Sopenharmony_ci */ 1582e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs 1583e5c31af7Sopenharmony_ci : public TransformFeedbackOverflowQuerySingleStreamBase 1584e5c31af7Sopenharmony_ci{ 1585e5c31af7Sopenharmony_cipublic: 1586e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs(deqp::Context& context, 1587e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, 1588e5c31af7Sopenharmony_ci const char* name) 1589e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQuerySingleStreamBase(context, api, name, 1590e5c31af7Sopenharmony_ci "Advanced single stream, interleaved attributes.") 1591e5c31af7Sopenharmony_ci { 1592e5c31af7Sopenharmony_ci } 1593e5c31af7Sopenharmony_ci 1594e5c31af7Sopenharmony_ci /* Use interleaved attributes. */ 1595e5c31af7Sopenharmony_ci virtual GLenum bufferMode() 1596e5c31af7Sopenharmony_ci { 1597e5c31af7Sopenharmony_ci return GL_INTERLEAVED_ATTRIBS; 1598e5c31af7Sopenharmony_ci } 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci /* A single transform feedback buffer is enough. */ 1601e5c31af7Sopenharmony_ci virtual GLsizei bufferCount() 1602e5c31af7Sopenharmony_ci { 1603e5c31af7Sopenharmony_ci return 1; 1604e5c31af7Sopenharmony_ci } 1605e5c31af7Sopenharmony_ci 1606e5c31af7Sopenharmony_ci /* The transform feedback buffer should be able to capture exactly 10 vertices. */ 1607e5c31af7Sopenharmony_ci virtual GLsizei bufferSize(GLint index) 1608e5c31af7Sopenharmony_ci { 1609e5c31af7Sopenharmony_ci (void)index; 1610e5c31af7Sopenharmony_ci return static_cast<GLsizei>(10 * sizeof(GLfloat) * varyingsCount()); 1611e5c31af7Sopenharmony_ci } 1612e5c31af7Sopenharmony_ci 1613e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 1614e5c31af7Sopenharmony_ci IterateResult iterate() 1615e5c31af7Sopenharmony_ci { 1616e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1617e5c31af7Sopenharmony_ci 1618e5c31af7Sopenharmony_ci // If GL 4.0 and ARB_transform_feedback2 are not supported then skip this 1619e5c31af7Sopenharmony_ci // test case. 1620e5c31af7Sopenharmony_ci if (!supportsTransformFeedback2()) 1621e5c31af7Sopenharmony_ci { 1622e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Required transform_feedback2 extension is not supported"); 1623e5c31af7Sopenharmony_ci } 1624e5c31af7Sopenharmony_ci 1625e5c31af7Sopenharmony_ci // Call BeginTransformFeedback with mode POINTS. 1626e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 1627e5c31af7Sopenharmony_ci 1628e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 8 1629e5c31af7Sopenharmony_ci // triangles, then stop the query. 1630e5c31af7Sopenharmony_ci drawPoints(8); 1631e5c31af7Sopenharmony_ci 1632e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 1633e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 1634e5c31af7Sopenharmony_ci 1635e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1636e5c31af7Sopenharmony_ci // query is FALSE. 1637e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1638e5c31af7Sopenharmony_ci 1639e5c31af7Sopenharmony_ci // Start the query, submit draw that would result in feeding back more than 1640e5c31af7Sopenharmony_ci // 10 points if transform feedback wasn't paused, then stop the query. 1641e5c31af7Sopenharmony_ci drawPoints(11); 1642e5c31af7Sopenharmony_ci 1643e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1644e5c31af7Sopenharmony_ci // query is FALSE. 1645e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1646e5c31af7Sopenharmony_ci 1647e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 1648e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 1 1651e5c31af7Sopenharmony_ci // point, then stop the query. 1652e5c31af7Sopenharmony_ci drawPoints(1); 1653e5c31af7Sopenharmony_ci 1654e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 1655e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 1656e5c31af7Sopenharmony_ci 1657e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1658e5c31af7Sopenharmony_ci // query is FALSE. 1659e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1660e5c31af7Sopenharmony_ci 1661e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 1662e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 1663e5c31af7Sopenharmony_ci 1664e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 2 1665e5c31af7Sopenharmony_ci // point, then stop the query. 1666e5c31af7Sopenharmony_ci drawPoints(2); 1667e5c31af7Sopenharmony_ci 1668e5c31af7Sopenharmony_ci // Call EndTransformFeedback. 1669e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 1670e5c31af7Sopenharmony_ci 1671e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1672e5c31af7Sopenharmony_ci // query is TRUE. 1673e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE); 1674e5c31af7Sopenharmony_ci 1675e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1676e5c31af7Sopenharmony_ci 1677e5c31af7Sopenharmony_ci return STOP; 1678e5c31af7Sopenharmony_ci } 1679e5c31af7Sopenharmony_ci}; 1680e5c31af7Sopenharmony_ci 1681e5c31af7Sopenharmony_ci/* 1682e5c31af7Sopenharmony_ci Test case #4 - Advanced single stream, separate attributes. 1683e5c31af7Sopenharmony_ci */ 1684e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs 1685e5c31af7Sopenharmony_ci : public TransformFeedbackOverflowQuerySingleStreamBase 1686e5c31af7Sopenharmony_ci{ 1687e5c31af7Sopenharmony_cipublic: 1688e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs(deqp::Context& context, 1689e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, 1690e5c31af7Sopenharmony_ci const char* name) 1691e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQuerySingleStreamBase(context, api, name, 1692e5c31af7Sopenharmony_ci "Advanced single stream, separate attributes.") 1693e5c31af7Sopenharmony_ci { 1694e5c31af7Sopenharmony_ci } 1695e5c31af7Sopenharmony_ci 1696e5c31af7Sopenharmony_ci /* Use separate attributes. */ 1697e5c31af7Sopenharmony_ci virtual GLenum bufferMode() 1698e5c31af7Sopenharmony_ci { 1699e5c31af7Sopenharmony_ci return GL_SEPARATE_ATTRIBS; 1700e5c31af7Sopenharmony_ci } 1701e5c31af7Sopenharmony_ci 1702e5c31af7Sopenharmony_ci /* We need a separate buffer for each varying. */ 1703e5c31af7Sopenharmony_ci virtual GLsizei bufferCount() 1704e5c31af7Sopenharmony_ci { 1705e5c31af7Sopenharmony_ci return varyingsCount(); 1706e5c31af7Sopenharmony_ci } 1707e5c31af7Sopenharmony_ci 1708e5c31af7Sopenharmony_ci /* One of the transform feedback buffers should be able to capture exactly 12 vertices, 1709e5c31af7Sopenharmony_ci the others should be able to capture at least 15 vertices. */ 1710e5c31af7Sopenharmony_ci virtual GLsizei bufferSize(GLint index) 1711e5c31af7Sopenharmony_ci { 1712e5c31af7Sopenharmony_ci if (index == 2) 1713e5c31af7Sopenharmony_ci { 1714e5c31af7Sopenharmony_ci return 12 * sizeof(GLfloat); 1715e5c31af7Sopenharmony_ci } 1716e5c31af7Sopenharmony_ci else 1717e5c31af7Sopenharmony_ci { 1718e5c31af7Sopenharmony_ci return 15 * sizeof(GLfloat); 1719e5c31af7Sopenharmony_ci } 1720e5c31af7Sopenharmony_ci } 1721e5c31af7Sopenharmony_ci 1722e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 1723e5c31af7Sopenharmony_ci IterateResult iterate() 1724e5c31af7Sopenharmony_ci { 1725e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1726e5c31af7Sopenharmony_ci 1727e5c31af7Sopenharmony_ci // If GL 4.0 and ARB_transform_feedback2 are not supported then skip this 1728e5c31af7Sopenharmony_ci // test case. 1729e5c31af7Sopenharmony_ci if (!supportsTransformFeedback2()) 1730e5c31af7Sopenharmony_ci { 1731e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Required transform_feedback2 extension is not supported"); 1732e5c31af7Sopenharmony_ci } 1733e5c31af7Sopenharmony_ci 1734e5c31af7Sopenharmony_ci // Call BeginTransformFeedback with mode TRIANGLES. 1735e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_TRIANGLES); 1736e5c31af7Sopenharmony_ci 1737e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 2 1738e5c31af7Sopenharmony_ci // triangles, then stop the query. 1739e5c31af7Sopenharmony_ci drawTriangles(2); 1740e5c31af7Sopenharmony_ci 1741e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 1742e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 1743e5c31af7Sopenharmony_ci 1744e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1745e5c31af7Sopenharmony_ci // query is FALSE. 1746e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1747e5c31af7Sopenharmony_ci 1748e5c31af7Sopenharmony_ci // Start the query, submit draw that would result in feeding back more than 1749e5c31af7Sopenharmony_ci // 4 triangles if transform feedback wasn't paused, then stop the query. 1750e5c31af7Sopenharmony_ci drawTriangles(4); 1751e5c31af7Sopenharmony_ci 1752e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1753e5c31af7Sopenharmony_ci // query is FALSE. 1754e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1755e5c31af7Sopenharmony_ci 1756e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 1757e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 1758e5c31af7Sopenharmony_ci 1759e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 2 1760e5c31af7Sopenharmony_ci // triangles, then stop the query. 1761e5c31af7Sopenharmony_ci drawTriangles(2); 1762e5c31af7Sopenharmony_ci 1763e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 1764e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1767e5c31af7Sopenharmony_ci // query is FALSE. 1768e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE); 1769e5c31af7Sopenharmony_ci 1770e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 1771e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 1772e5c31af7Sopenharmony_ci 1773e5c31af7Sopenharmony_ci // Start the query, submit draw that results in feeding back exactly 1 1774e5c31af7Sopenharmony_ci // triangles, then stop the query. 1775e5c31af7Sopenharmony_ci drawTriangles(1); 1776e5c31af7Sopenharmony_ci 1777e5c31af7Sopenharmony_ci // Call EndTransformFeedback. 1778e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 1779e5c31af7Sopenharmony_ci 1780e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1781e5c31af7Sopenharmony_ci // query is TRUE. 1782e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE); 1783e5c31af7Sopenharmony_ci 1784e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1785e5c31af7Sopenharmony_ci 1786e5c31af7Sopenharmony_ci return STOP; 1787e5c31af7Sopenharmony_ci } 1788e5c31af7Sopenharmony_ci}; 1789e5c31af7Sopenharmony_ci 1790e5c31af7Sopenharmony_ci/* 1791e5c31af7Sopenharmony_ci Base class for all multiple stream test cases. 1792e5c31af7Sopenharmony_ci */ 1793e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryMultipleStreamsBase : public TransformFeedbackOverflowQueryFunctionalBase 1794e5c31af7Sopenharmony_ci{ 1795e5c31af7Sopenharmony_ciprotected: 1796e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryMultipleStreamsBase(deqp::Context& context, 1797e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, const char* name, 1798e5c31af7Sopenharmony_ci const char* description) 1799e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryFunctionalBase(context, api, name, description) 1800e5c31af7Sopenharmony_ci { 1801e5c31af7Sopenharmony_ci } 1802e5c31af7Sopenharmony_ci 1803e5c31af7Sopenharmony_ci /* Vertex shader to use for transform feedback. */ 1804e5c31af7Sopenharmony_ci virtual const char* transformFeedbackVertexShader() 1805e5c31af7Sopenharmony_ci { 1806e5c31af7Sopenharmony_ci return "#version 150 core\n" 1807e5c31af7Sopenharmony_ci "void main() {\n" 1808e5c31af7Sopenharmony_ci "}"; 1809e5c31af7Sopenharmony_ci } 1810e5c31af7Sopenharmony_ci 1811e5c31af7Sopenharmony_ci /* Use interleaved attributes. */ 1812e5c31af7Sopenharmony_ci virtual GLenum bufferMode() 1813e5c31af7Sopenharmony_ci { 1814e5c31af7Sopenharmony_ci return GL_INTERLEAVED_ATTRIBS; 1815e5c31af7Sopenharmony_ci } 1816e5c31af7Sopenharmony_ci 1817e5c31af7Sopenharmony_ci /* Always use 4 transform feedback buffers. */ 1818e5c31af7Sopenharmony_ci virtual GLsizei bufferCount() 1819e5c31af7Sopenharmony_ci { 1820e5c31af7Sopenharmony_ci return 4; 1821e5c31af7Sopenharmony_ci } 1822e5c31af7Sopenharmony_ci 1823e5c31af7Sopenharmony_ci /* Draws a set of points to each vertex stream while having the overflow queries active. */ 1824e5c31af7Sopenharmony_ci void drawStreams(GLsizei count0, GLsizei count1 = 0, GLsizei count2 = 0, GLsizei count3 = 0) 1825e5c31af7Sopenharmony_ci { 1826e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1827e5c31af7Sopenharmony_ci 1828e5c31af7Sopenharmony_ci GLint streamLoc = gl.getUniformLocation(m_program, "stream"); 1829e5c31af7Sopenharmony_ci 1830e5c31af7Sopenharmony_ci beginQueries(); 1831e5c31af7Sopenharmony_ci 1832e5c31af7Sopenharmony_ci gl.uniform1ui(streamLoc, 0); 1833e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, count0); 1834e5c31af7Sopenharmony_ci 1835e5c31af7Sopenharmony_ci gl.uniform1ui(streamLoc, 1); 1836e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, count1); 1837e5c31af7Sopenharmony_ci 1838e5c31af7Sopenharmony_ci gl.uniform1ui(streamLoc, 2); 1839e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, count2); 1840e5c31af7Sopenharmony_ci 1841e5c31af7Sopenharmony_ci gl.uniform1ui(streamLoc, 3); 1842e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, count3); 1843e5c31af7Sopenharmony_ci 1844e5c31af7Sopenharmony_ci endQueries(); 1845e5c31af7Sopenharmony_ci } 1846e5c31af7Sopenharmony_ci}; 1847e5c31af7Sopenharmony_ci 1848e5c31af7Sopenharmony_ci/* 1849e5c31af7Sopenharmony_ci Test case #5 - Advanced multiple streams, one buffer per stream. 1850e5c31af7Sopenharmony_ci */ 1851e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream 1852e5c31af7Sopenharmony_ci : public TransformFeedbackOverflowQueryMultipleStreamsBase 1853e5c31af7Sopenharmony_ci{ 1854e5c31af7Sopenharmony_cipublic: 1855e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream(deqp::Context& context, 1856e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, 1857e5c31af7Sopenharmony_ci const char* name) 1858e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryMultipleStreamsBase(context, api, name, 1859e5c31af7Sopenharmony_ci "Advanced multiple streams, one buffer per stream.") 1860e5c31af7Sopenharmony_ci { 1861e5c31af7Sopenharmony_ci } 1862e5c31af7Sopenharmony_ci 1863e5c31af7Sopenharmony_ci /* Geometry shader to use for transform feedback. */ 1864e5c31af7Sopenharmony_ci virtual const char* transformFeedbackGeometryShader() 1865e5c31af7Sopenharmony_ci { 1866e5c31af7Sopenharmony_ci return "#version 150 core\n" 1867e5c31af7Sopenharmony_ci "#extension GL_ARB_gpu_shader5 : require\n" 1868e5c31af7Sopenharmony_ci "layout(points) in;\n" 1869e5c31af7Sopenharmony_ci "layout(points, max_vertices = 1) out;\n" 1870e5c31af7Sopenharmony_ci "layout(stream=0) out float output1;\n" 1871e5c31af7Sopenharmony_ci "layout(stream=1) out float output2;\n" 1872e5c31af7Sopenharmony_ci "layout(stream=2) out float output3;\n" 1873e5c31af7Sopenharmony_ci "layout(stream=3) out float output4;\n" 1874e5c31af7Sopenharmony_ci "uniform uint stream;\n" 1875e5c31af7Sopenharmony_ci "void main() {\n" 1876e5c31af7Sopenharmony_ci " if (stream == 0) {\n" 1877e5c31af7Sopenharmony_ci " output1 = 1.0;\n" 1878e5c31af7Sopenharmony_ci " EmitStreamVertex(0);\n" 1879e5c31af7Sopenharmony_ci " EndStreamPrimitive(0);\n" 1880e5c31af7Sopenharmony_ci " }\n" 1881e5c31af7Sopenharmony_ci " if (stream == 1) {\n" 1882e5c31af7Sopenharmony_ci " output2 = 2.0;\n" 1883e5c31af7Sopenharmony_ci " EmitStreamVertex(1);\n" 1884e5c31af7Sopenharmony_ci " EndStreamPrimitive(1);\n" 1885e5c31af7Sopenharmony_ci " }\n" 1886e5c31af7Sopenharmony_ci " if (stream == 2) {\n" 1887e5c31af7Sopenharmony_ci " output3 = 3.0;\n" 1888e5c31af7Sopenharmony_ci " EmitStreamVertex(2);\n" 1889e5c31af7Sopenharmony_ci " EndStreamPrimitive(2);\n" 1890e5c31af7Sopenharmony_ci " }\n" 1891e5c31af7Sopenharmony_ci " if (stream == 3) {\n" 1892e5c31af7Sopenharmony_ci " output4 = 4.0;\n" 1893e5c31af7Sopenharmony_ci " EmitStreamVertex(3);\n" 1894e5c31af7Sopenharmony_ci " EndStreamPrimitive(3);\n" 1895e5c31af7Sopenharmony_ci " }\n" 1896e5c31af7Sopenharmony_ci "}"; 1897e5c31af7Sopenharmony_ci } 1898e5c31af7Sopenharmony_ci 1899e5c31af7Sopenharmony_ci /* Together with the separators there are a total of 7 varyings. */ 1900e5c31af7Sopenharmony_ci virtual GLsizei varyingsCount() 1901e5c31af7Sopenharmony_ci { 1902e5c31af7Sopenharmony_ci return 7; 1903e5c31af7Sopenharmony_ci } 1904e5c31af7Sopenharmony_ci 1905e5c31af7Sopenharmony_ci /* Each output goes to different buffer. The mapping between vertex stream outputs and transform feedback buffers is non-identity. */ 1906e5c31af7Sopenharmony_ci virtual const char** varyings() 1907e5c31af7Sopenharmony_ci { 1908e5c31af7Sopenharmony_ci static const char* vars[] = { "output4", "gl_NextBuffer", "output3", "gl_NextBuffer", 1909e5c31af7Sopenharmony_ci "output2", "gl_NextBuffer", "output1" }; 1910e5c31af7Sopenharmony_ci return vars; 1911e5c31af7Sopenharmony_ci } 1912e5c31af7Sopenharmony_ci 1913e5c31af7Sopenharmony_ci /* The size of the transform feedback buffers should be enough to be able to capture exactly 10 vertices for each vertex stream. */ 1914e5c31af7Sopenharmony_ci virtual GLsizei bufferSize(GLint index) 1915e5c31af7Sopenharmony_ci { 1916e5c31af7Sopenharmony_ci (void)index; 1917e5c31af7Sopenharmony_ci return 10 * sizeof(GLfloat); 1918e5c31af7Sopenharmony_ci } 1919e5c31af7Sopenharmony_ci 1920e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 1921e5c31af7Sopenharmony_ci IterateResult iterate() 1922e5c31af7Sopenharmony_ci { 1923e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1924e5c31af7Sopenharmony_ci 1925e5c31af7Sopenharmony_ci // If GL 4.0 and ARB_transform_feedback3 are not supported then skip this 1926e5c31af7Sopenharmony_ci // test case. 1927e5c31af7Sopenharmony_ci if (!supportsTransformFeedback3()) 1928e5c31af7Sopenharmony_ci { 1929e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Required transform_feedback3 extension is not supported"); 1930e5c31af7Sopenharmony_ci } 1931e5c31af7Sopenharmony_ci 1932e5c31af7Sopenharmony_ci // If GL 4.0 and ARB_gpu_shader5 are not supported then skip this 1933e5c31af7Sopenharmony_ci // test case. 1934e5c31af7Sopenharmony_ci if (!supportsGpuShader5()) 1935e5c31af7Sopenharmony_ci { 1936e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Required gpu_shader5 extension is not supported"); 1937e5c31af7Sopenharmony_ci } 1938e5c31af7Sopenharmony_ci 1939e5c31af7Sopenharmony_ci // Call BeginTransformFeedback with mode POINTS. 1940e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 1941e5c31af7Sopenharmony_ci 1942e5c31af7Sopenharmony_ci // Start all queries, submit draw that results in feeding back exactly 8 1943e5c31af7Sopenharmony_ci // points for all four vertex streams, then stop the queries. 1944e5c31af7Sopenharmony_ci drawStreams(8, 8, 8, 8); 1945e5c31af7Sopenharmony_ci 1946e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 1947e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 1948e5c31af7Sopenharmony_ci 1949e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1950e5c31af7Sopenharmony_ci // queries are all FALSE. 1951e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1952e5c31af7Sopenharmony_ci 1953e5c31af7Sopenharmony_ci // Start the queries, submit draw that would result in feeding back more 1954e5c31af7Sopenharmony_ci // than 10 points for all four vertex streams if transform feedback wasn't 1955e5c31af7Sopenharmony_ci // paused, then stop the queries. 1956e5c31af7Sopenharmony_ci drawStreams(11, 11, 11, 11); 1957e5c31af7Sopenharmony_ci 1958e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1959e5c31af7Sopenharmony_ci // queries are all FALSE. 1960e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1961e5c31af7Sopenharmony_ci 1962e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 1963e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 1964e5c31af7Sopenharmony_ci 1965e5c31af7Sopenharmony_ci // Start the queries, submit draw that results in feeding back exactly 3 1966e5c31af7Sopenharmony_ci // points only for vertex streams #1 and #3, then stop the queries. 1967e5c31af7Sopenharmony_ci drawStreams(0, 3, 0, 3); 1968e5c31af7Sopenharmony_ci 1969e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 1970e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 1971e5c31af7Sopenharmony_ci 1972e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1973e5c31af7Sopenharmony_ci // queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW 1974e5c31af7Sopenharmony_ci // query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for 1975e5c31af7Sopenharmony_ci // vertex streams #1 and #3, which should have a TRUE result. 1976e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); 1977e5c31af7Sopenharmony_ci 1978e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 1979e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 1980e5c31af7Sopenharmony_ci 1981e5c31af7Sopenharmony_ci // Start the queries, submit draw that results in feeding back exactly 2 1982e5c31af7Sopenharmony_ci // points only for vertex streams #0 and #2, then stop the queries. 1983e5c31af7Sopenharmony_ci drawStreams(2, 0, 2, 0); 1984e5c31af7Sopenharmony_ci 1985e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 1986e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 1987e5c31af7Sopenharmony_ci 1988e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 1989e5c31af7Sopenharmony_ci // queries are all FALSE. 1990e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1991e5c31af7Sopenharmony_ci 1992e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 1993e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 1994e5c31af7Sopenharmony_ci 1995e5c31af7Sopenharmony_ci // Start the queries, submit draw that results in feeding back exactly 1 1996e5c31af7Sopenharmony_ci // point for vertex streams #2 and #3, then stop the queries. 1997e5c31af7Sopenharmony_ci drawStreams(0, 0, 1, 1); 1998e5c31af7Sopenharmony_ci 1999e5c31af7Sopenharmony_ci // Call EndTransformFeedback. 2000e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 2001e5c31af7Sopenharmony_ci 2002e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 2003e5c31af7Sopenharmony_ci // queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW 2004e5c31af7Sopenharmony_ci // query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for 2005e5c31af7Sopenharmony_ci // vertex streams #2 and #3, which should have a TRUE result. 2006e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); 2007e5c31af7Sopenharmony_ci 2008e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2009e5c31af7Sopenharmony_ci 2010e5c31af7Sopenharmony_ci return STOP; 2011e5c31af7Sopenharmony_ci } 2012e5c31af7Sopenharmony_ci}; 2013e5c31af7Sopenharmony_ci 2014e5c31af7Sopenharmony_ci/* 2015e5c31af7Sopenharmony_ci Test case #6 - Advanced multiple streams, multiple buffers per stream. 2016e5c31af7Sopenharmony_ci */ 2017e5c31af7Sopenharmony_ciclass TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream 2018e5c31af7Sopenharmony_ci : public TransformFeedbackOverflowQueryMultipleStreamsBase 2019e5c31af7Sopenharmony_ci{ 2020e5c31af7Sopenharmony_cipublic: 2021e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream(deqp::Context& context, 2022e5c31af7Sopenharmony_ci TransformFeedbackOverflowQueryTests::API api, 2023e5c31af7Sopenharmony_ci const char* name) 2024e5c31af7Sopenharmony_ci : TransformFeedbackOverflowQueryMultipleStreamsBase(context, api, name, 2025e5c31af7Sopenharmony_ci "Advanced multiple streams, multiple buffers per stream.") 2026e5c31af7Sopenharmony_ci { 2027e5c31af7Sopenharmony_ci } 2028e5c31af7Sopenharmony_ci 2029e5c31af7Sopenharmony_ci /* Geometry shader to use for transform feedback. */ 2030e5c31af7Sopenharmony_ci virtual const char* transformFeedbackGeometryShader() 2031e5c31af7Sopenharmony_ci { 2032e5c31af7Sopenharmony_ci return "#version 150 core\n" 2033e5c31af7Sopenharmony_ci "#extension GL_ARB_gpu_shader5 : require\n" 2034e5c31af7Sopenharmony_ci "layout(points) in;\n" 2035e5c31af7Sopenharmony_ci "layout(points, max_vertices = 1) out;\n" 2036e5c31af7Sopenharmony_ci "layout(stream=0) out float output1;\n" 2037e5c31af7Sopenharmony_ci "layout(stream=0) out float output2;\n" 2038e5c31af7Sopenharmony_ci "layout(stream=1) out float output3;\n" 2039e5c31af7Sopenharmony_ci "layout(stream=1) out float output4;\n" 2040e5c31af7Sopenharmony_ci "uniform uint stream;\n" 2041e5c31af7Sopenharmony_ci "void main() {\n" 2042e5c31af7Sopenharmony_ci " if (stream == 0) {\n" 2043e5c31af7Sopenharmony_ci " output1 = 1.0;\n" 2044e5c31af7Sopenharmony_ci " output2 = 2.0;\n" 2045e5c31af7Sopenharmony_ci " EmitStreamVertex(0);\n" 2046e5c31af7Sopenharmony_ci " EndStreamPrimitive(0);\n" 2047e5c31af7Sopenharmony_ci " }\n" 2048e5c31af7Sopenharmony_ci " if (stream == 1) {\n" 2049e5c31af7Sopenharmony_ci " output3 = 3.0;\n" 2050e5c31af7Sopenharmony_ci " output4 = 4.0;\n" 2051e5c31af7Sopenharmony_ci " EmitStreamVertex(1);\n" 2052e5c31af7Sopenharmony_ci " EndStreamPrimitive(1);\n" 2053e5c31af7Sopenharmony_ci " }\n" 2054e5c31af7Sopenharmony_ci "}"; 2055e5c31af7Sopenharmony_ci } 2056e5c31af7Sopenharmony_ci 2057e5c31af7Sopenharmony_ci /* Together with the separators there are a total of 7 varyings. */ 2058e5c31af7Sopenharmony_ci virtual GLsizei varyingsCount() 2059e5c31af7Sopenharmony_ci { 2060e5c31af7Sopenharmony_ci return 7; 2061e5c31af7Sopenharmony_ci } 2062e5c31af7Sopenharmony_ci 2063e5c31af7Sopenharmony_ci /* Vertex stream #0 is captured by transform feedback buffers #1 and #2, while 2064e5c31af7Sopenharmony_ci vertex stream #1 is captured by transform feedback buffers #3 and #0. */ 2065e5c31af7Sopenharmony_ci virtual const char** varyings() 2066e5c31af7Sopenharmony_ci { 2067e5c31af7Sopenharmony_ci static const char* vars[] = { "output4", "gl_NextBuffer", "output1", "gl_NextBuffer", 2068e5c31af7Sopenharmony_ci "output2", "gl_NextBuffer", "output3" }; 2069e5c31af7Sopenharmony_ci return vars; 2070e5c31af7Sopenharmony_ci } 2071e5c31af7Sopenharmony_ci 2072e5c31af7Sopenharmony_ci /* Transform feedback buffers #0 and #1 should be able to capture exactly 10 vertices, while 2073e5c31af7Sopenharmony_ci transform feedback buffers #2 and #3 should be able to capture exactly 20 vertices. */ 2074e5c31af7Sopenharmony_ci virtual GLsizei bufferSize(GLint index) 2075e5c31af7Sopenharmony_ci { 2076e5c31af7Sopenharmony_ci if (index < 2) 2077e5c31af7Sopenharmony_ci { 2078e5c31af7Sopenharmony_ci return 10 * sizeof(GLfloat); 2079e5c31af7Sopenharmony_ci } 2080e5c31af7Sopenharmony_ci else 2081e5c31af7Sopenharmony_ci { 2082e5c31af7Sopenharmony_ci return 20 * sizeof(GLfloat); 2083e5c31af7Sopenharmony_ci } 2084e5c31af7Sopenharmony_ci } 2085e5c31af7Sopenharmony_ci 2086e5c31af7Sopenharmony_ci /* Test case iterate function. Contains the actual test case logic. */ 2087e5c31af7Sopenharmony_ci IterateResult iterate() 2088e5c31af7Sopenharmony_ci { 2089e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2090e5c31af7Sopenharmony_ci 2091e5c31af7Sopenharmony_ci // If GL 4.0 and ARB_transform_feedback3 are not supported then skip this 2092e5c31af7Sopenharmony_ci // test case. 2093e5c31af7Sopenharmony_ci if (!supportsTransformFeedback3()) 2094e5c31af7Sopenharmony_ci { 2095e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Required transform_feedback3 extension is not supported"); 2096e5c31af7Sopenharmony_ci } 2097e5c31af7Sopenharmony_ci 2098e5c31af7Sopenharmony_ci // If GL 4.0 and ARB_gpu_shader5 are not supported then skip this 2099e5c31af7Sopenharmony_ci // test case. 2100e5c31af7Sopenharmony_ci if (!supportsGpuShader5()) 2101e5c31af7Sopenharmony_ci { 2102e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Required gpu_shader5 extension is not supported"); 2103e5c31af7Sopenharmony_ci } 2104e5c31af7Sopenharmony_ci 2105e5c31af7Sopenharmony_ci // Call BeginTransformFeedback with mode POINTS. 2106e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 2107e5c31af7Sopenharmony_ci 2108e5c31af7Sopenharmony_ci // Start all queries, submit draw that results in feeding back exactly 8 2109e5c31af7Sopenharmony_ci // points to both vertex streams, then stop the queries. 2110e5c31af7Sopenharmony_ci drawStreams(8, 8); 2111e5c31af7Sopenharmony_ci 2112e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 2113e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 2114e5c31af7Sopenharmony_ci 2115e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 2116e5c31af7Sopenharmony_ci // queries are all FALSE. 2117e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE); 2118e5c31af7Sopenharmony_ci 2119e5c31af7Sopenharmony_ci // Start the queries, submit draw that would result in feeding back more 2120e5c31af7Sopenharmony_ci // than 10 points for both vertex streams if transform feedback wasn't 2121e5c31af7Sopenharmony_ci // paused, then stop the queries. 2122e5c31af7Sopenharmony_ci drawStreams(11, 11); 2123e5c31af7Sopenharmony_ci 2124e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 2125e5c31af7Sopenharmony_ci // queries are all FALSE. 2126e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE); 2127e5c31af7Sopenharmony_ci 2128e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 2129e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 2130e5c31af7Sopenharmony_ci 2131e5c31af7Sopenharmony_ci // Start the queries, submit draw that results in feeding back exactly 1 2132e5c31af7Sopenharmony_ci // point for vertex stream #0 and exactly 3 points for vertex stream #1, 2133e5c31af7Sopenharmony_ci // then stop the queries. 2134e5c31af7Sopenharmony_ci drawStreams(1, 3); 2135e5c31af7Sopenharmony_ci 2136e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 2137e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 2138e5c31af7Sopenharmony_ci 2139e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 2140e5c31af7Sopenharmony_ci // queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW 2141e5c31af7Sopenharmony_ci // query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW query for vertex 2142e5c31af7Sopenharmony_ci // stream #1, which should have a TRUE result. 2143e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE, GL_FALSE, GL_TRUE); 2144e5c31af7Sopenharmony_ci 2145e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 2146e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 2147e5c31af7Sopenharmony_ci 2148e5c31af7Sopenharmony_ci // Start the queries, submit draw that results in feeding back exactly 1 2149e5c31af7Sopenharmony_ci // point only for vertex stream #0, then stop the queries. 2150e5c31af7Sopenharmony_ci drawStreams(1, 0); 2151e5c31af7Sopenharmony_ci 2152e5c31af7Sopenharmony_ci // Call PauseTransformFeedback. 2153e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 2154e5c31af7Sopenharmony_ci 2155e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 2156e5c31af7Sopenharmony_ci // queries are all FALSE. 2157e5c31af7Sopenharmony_ci verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE); 2158e5c31af7Sopenharmony_ci 2159e5c31af7Sopenharmony_ci // Call ResumeTransformFeedback. 2160e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 2161e5c31af7Sopenharmony_ci 2162e5c31af7Sopenharmony_ci // Start the queries, submit draw that results in feeding back exactly 1 2163e5c31af7Sopenharmony_ci // point for vertex streams #0 and #1, then stop the queries. 2164e5c31af7Sopenharmony_ci drawStreams(1, 1); 2165e5c31af7Sopenharmony_ci 2166e5c31af7Sopenharmony_ci // Call EndTransformFeedback. 2167e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 2168e5c31af7Sopenharmony_ci 2169e5c31af7Sopenharmony_ci // Use the basic checking mechanism to validate that the result of the 2170e5c31af7Sopenharmony_ci // queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW 2171e5c31af7Sopenharmony_ci // query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for 2172e5c31af7Sopenharmony_ci // vertex streams #0 and #1, which should have a TRUE result. 2173e5c31af7Sopenharmony_ci verifyQueryResults(GL_TRUE, GL_TRUE, GL_TRUE); 2174e5c31af7Sopenharmony_ci 2175e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2176e5c31af7Sopenharmony_ci 2177e5c31af7Sopenharmony_ci return STOP; 2178e5c31af7Sopenharmony_ci } 2179e5c31af7Sopenharmony_ci}; 2180e5c31af7Sopenharmony_ci 2181e5c31af7Sopenharmony_ciconst char* apiToTestName(TransformFeedbackOverflowQueryTests::API api) 2182e5c31af7Sopenharmony_ci{ 2183e5c31af7Sopenharmony_ci switch (api) 2184e5c31af7Sopenharmony_ci { 2185e5c31af7Sopenharmony_ci case TransformFeedbackOverflowQueryTests::API_GL_ARB_transform_feedback_overflow_query: 2186e5c31af7Sopenharmony_ci return "transform_feedback_overflow_query_ARB"; 2187e5c31af7Sopenharmony_ci } 2188e5c31af7Sopenharmony_ci DE_ASSERT(0); 2189e5c31af7Sopenharmony_ci return ""; 2190e5c31af7Sopenharmony_ci} 2191e5c31af7Sopenharmony_ci 2192e5c31af7Sopenharmony_ci/** Constructor. 2193e5c31af7Sopenharmony_ci * 2194e5c31af7Sopenharmony_ci * @param context Rendering context. 2195e5c31af7Sopenharmony_ci * @param api API to test (core vs ARB extension) 2196e5c31af7Sopenharmony_ci **/ 2197e5c31af7Sopenharmony_ciTransformFeedbackOverflowQueryTests::TransformFeedbackOverflowQueryTests(deqp::Context& context, API api) 2198e5c31af7Sopenharmony_ci : TestCaseGroup(context, apiToTestName(api), "Verifies \"transform_feedback_overflow_query\" functionality") 2199e5c31af7Sopenharmony_ci , m_api(api) 2200e5c31af7Sopenharmony_ci{ 2201e5c31af7Sopenharmony_ci /* Left blank on purpose */ 2202e5c31af7Sopenharmony_ci} 2203e5c31af7Sopenharmony_ci 2204e5c31af7Sopenharmony_ci/** Destructor. 2205e5c31af7Sopenharmony_ci * 2206e5c31af7Sopenharmony_ci **/ 2207e5c31af7Sopenharmony_ciTransformFeedbackOverflowQueryTests::~TransformFeedbackOverflowQueryTests() 2208e5c31af7Sopenharmony_ci{ 2209e5c31af7Sopenharmony_ci} 2210e5c31af7Sopenharmony_ci 2211e5c31af7Sopenharmony_ci/** Initializes the texture_barrier test group. 2212e5c31af7Sopenharmony_ci * 2213e5c31af7Sopenharmony_ci **/ 2214e5c31af7Sopenharmony_civoid TransformFeedbackOverflowQueryTests::init(void) 2215e5c31af7Sopenharmony_ci{ 2216e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryImplDepState(m_context, m_api, "implementation-dependent-state")); 2217e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryDefaultState(m_context, m_api, "default-context-state")); 2218e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryStateUpdate(m_context, m_api, "context-state-update")); 2219e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryErrorInvalidIndex(m_context, m_api, "error-invalid-index")); 2220e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryErrorAlreadyActive(m_context, m_api, "error-already-active")); 2221e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryErrorIncompatibleTarget(m_context, m_api, "error-incompatible-target")); 2222e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryErrorNoActiveQuery(m_context, m_api, "error-no-active-query")); 2223e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs( 2224e5c31af7Sopenharmony_ci m_context, m_api, "basic-single-stream-interleaved-attribs")); 2225e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs( 2226e5c31af7Sopenharmony_ci m_context, m_api, "basic-single-stream-separate-attribs")); 2227e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs( 2228e5c31af7Sopenharmony_ci m_context, m_api, "advanced-single-stream-interleaved-attribs")); 2229e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs( 2230e5c31af7Sopenharmony_ci m_context, m_api, "advanced-single-stream-separate-attribs")); 2231e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream( 2232e5c31af7Sopenharmony_ci m_context, m_api, "multiple-streams-one-buffer-per-stream")); 2233e5c31af7Sopenharmony_ci addChild(new TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream( 2234e5c31af7Sopenharmony_ci m_context, m_api, "multiple-streams-multiple-buffers-per-stream")); 2235e5c31af7Sopenharmony_ci} 2236e5c31af7Sopenharmony_ci} /* glcts namespace */ 2237