1e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/*------------------------------------------------------------------------- 2e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * drawElements Quality Program OpenGL ES 3.0 Module 3e9629bad30a9f478b336ab46b8e6e02f7f87af46Evan Chu * ------------------------------------------------- 4e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * 5e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * Copyright 2014 The Android Open Source Project 6e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * 7e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 8e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * you may not use this file except in compliance with the License. 9e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * You may obtain a copy of the License at 10e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * 11e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 12e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * 13e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 14e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 15e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * See the License for the specific language governing permissions and 17e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * limitations under the License. 18e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * 195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *//*! 20e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * \file 21e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * \brief Transform feedback tests. 22e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *//*--------------------------------------------------------------------*/ 23e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 24e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "es3fTransformFeedbackTests.hpp" 25e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "tcuTestLog.hpp" 26e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "tcuSurface.hpp" 27e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "tcuImageCompare.hpp" 28e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "tcuVector.hpp" 29e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "tcuFormatUtil.hpp" 30e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "tcuRenderTarget.hpp" 31e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gluShaderUtil.hpp" 32e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gluVarType.hpp" 33e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gluVarTypeUtil.hpp" 34e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gluPixelTransfer.hpp" 35e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gluRenderContext.hpp" 36e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gluShaderProgram.hpp" 37e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "gluObjectWrapper.hpp" 38e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "glwFunctions.hpp" 39e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "glwEnums.hpp" 40e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "deRandom.hpp" 41e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "deStringUtil.hpp" 42e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "deMemory.h" 43e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "deString.h" 44e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 45e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <set> 46e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <map> 47e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <algorithm> 48e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 49e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectusing std::string; 50e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectusing std::vector; 51e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectusing std::set; 52e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 53e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectusing std::map; 54e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectusing std::set; 55e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 56e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectusing tcu::TestLog; 57e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 58e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectnamespace deqp 59e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 60e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectnamespace gles3 61e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 62e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectnamespace Functional 63e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 64e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectnamespace TransformFeedback 65e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 66e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 67e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectenum 68e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 69e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project VIEWPORT_WIDTH = 128, 70e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project VIEWPORT_HEIGHT = 128, 71e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BUFFER_GUARD_MULTIPLIER = 2 //!< stride*BUFFER_GUARD_MULTIPLIER bytes are added to the end of tf buffer and used to check for overruns. 72e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 73e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 74e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectenum Interpolation 75e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 76e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project INTERPOLATION_SMOOTH = 0, 77e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project INTERPOLATION_FLAT, 78e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project INTERPOLATION_CENTROID, 79e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 80e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project INTERPOLATION_LAST 81e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 82e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 83e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic const char* getInterpolationName (Interpolation interp) 84e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 85e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (interp) 86e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 87e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case INTERPOLATION_SMOOTH: return "smooth"; 88e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case INTERPOLATION_FLAT: return "flat"; 895c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case INTERPOLATION_CENTROID: return "centroid"; 90e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 91e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 92e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return DE_NULL; 93e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 94e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 95e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 96e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstruct Varying 97e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 98e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Varying (const char* name_, const glu::VarType& type_, Interpolation interp_) 99e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : name (name_) 100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , type (type_) 1015c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen , interpolation (interp_) 102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string name; //!< Variable name. 106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::VarType type; //!< Variable type. 107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Interpolation interpolation; //!< Interpolation mode (smooth, flat, centroid). 108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstruct VaryingNameEquals 111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project VaryingNameEquals (const std::string& name_) : name(name_) {} 113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool operator() (const Varying& var) const { return var.name == name; } 114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string name; 116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstruct Attribute 119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Attribute (const std::string& name_, const glu::VarType& type_, int offset_) 121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : name (name_) 122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , type (type_) 123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , offset (offset_) 124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string name; 128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::VarType type; 129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int offset; 130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstruct AttributeNameEquals 133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project AttributeNameEquals (const std::string& name_) : name(name_) {} 135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool operator() (const Attribute& attr) const { return attr.name == name; } 136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string name; 138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 1395c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1405c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenstruct Output 141a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu{ 142a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu Output (void) 143a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu : bufferNdx (0) 144a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu , offset (0) 145a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu { 146a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu } 147a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu 148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string name; 149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::VarType type; 150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int bufferNdx; 151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int offset; 152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<const Attribute*> inputs; 153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstruct DrawCall 156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DrawCall (int numElements_, bool tfEnabled_) 158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : numElements (numElements_) 159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , transformFeedbackEnabled (tfEnabled_) 160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DrawCall (void) 164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : numElements (0) 165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , transformFeedbackEnabled (false) 166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numElements; 170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool transformFeedbackEnabled; 171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstd::ostream& operator<< (std::ostream& str, const DrawCall& call) 174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return str << "(" << call.numElements << ", " << (call.transformFeedbackEnabled ? "resumed" : "paused") << ")"; 176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 178e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectclass ProgramSpec 179e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectpublic: 181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ProgramSpec (void); 182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ~ProgramSpec (void); 1835c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::StructType* createStruct (const char* name); 185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project void addVarying (const char* name, const glu::VarType& type, Interpolation interp); 186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project void addTransformFeedbackVarying (const char* name); 187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const vector<glu::StructType*>& getStructs (void) const { return m_structs; } 189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const vector<Varying>& getVaryings (void) const { return m_varyings; } 190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const vector<string>& getTransformFeedbackVaryings (void) const { return m_transformFeedbackVaryings; } 191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool isPointSizeUsed (void) const; 192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectprivate: 194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ProgramSpec (const ProgramSpec& other); 195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ProgramSpec& operator= (const ProgramSpec& other); 196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<glu::StructType*> m_structs; 198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<Varying> m_varyings; 199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<string> m_transformFeedbackVaryings; 200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// ProgramSpec 203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectProgramSpec::ProgramSpec (void) 205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectProgramSpec::~ProgramSpec (void) 209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<glu::StructType*>::iterator i = m_structs.begin(); i != m_structs.end(); i++) 211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project delete *i; 212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectglu::StructType* ProgramSpec::createStruct (const char* name) 215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_structs.reserve(m_structs.size()+1); 217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_structs.push_back(new glu::StructType(name)); 218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return m_structs.back(); 219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ProgramSpec::addVarying (const char* name, const glu::VarType& type, Interpolation interp) 222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_varyings.push_back(Varying(name, type, interp)); 224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid ProgramSpec::addTransformFeedbackVarying (const char* name) 227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_transformFeedbackVaryings.push_back(name); 229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool ProgramSpec::isPointSizeUsed (void) const 232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return std::find(m_transformFeedbackVaryings.begin(), m_transformFeedbackVaryings.end(), "gl_PointSize") != m_transformFeedbackVaryings.end(); 234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic bool isProgramSupported (const glw::Functions& gl, const ProgramSpec& spec, deUint32 tfMode) 237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int maxVertexAttribs = 0; 239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int maxTfInterleavedComponents = 0; 240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int maxTfSeparateAttribs = 0; 241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int maxTfSeparateComponents = 0; 242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); 244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &maxTfInterleavedComponents); 245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxTfSeparateAttribs); 246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &maxTfSeparateComponents); 247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Check vertex attribs. 249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int totalVertexAttribs = 1 /* a_position */ + (spec.isPointSizeUsed() ? 1 : 0); 250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Varying>::const_iterator var = spec.getVaryings().begin(); var != spec.getVaryings().end(); var++) 251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (glu::VectorTypeIterator vecIter = glu::VectorTypeIterator::begin(&var->type); vecIter != glu::VectorTypeIterator::end(&var->type); vecIter++) 253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project totalVertexAttribs += 1; 254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (totalVertexAttribs > maxVertexAttribs) 257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; // Vertex attribute count exceeded. 258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Check varyings. 260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int totalTfComponents = 0; 261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int totalTfAttribs = 0; 262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<string>::const_iterator iter = spec.getTransformFeedbackVaryings().begin(); iter != spec.getTransformFeedbackVaryings().end(); iter++) 263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const string& name = *iter; 265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numComponents = 0; 266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (name == "gl_Position") 268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project numComponents = 4; 269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (name == "gl_PointSize") 270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project numComponents = 1; 271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else 272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project string varName = glu::parseVariableName(name.c_str()); 274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const Varying& varying = *std::find_if(spec.getVaryings().begin(), spec.getVaryings().end(), VaryingNameEquals(varName)); 275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::TypeComponentVector varPath; 276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::parseTypePath(name.c_str(), varying.type, varPath); 278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project numComponents = glu::getVarType(varying.type, varPath).getScalarSize(); 279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (tfMode == GL_SEPARATE_ATTRIBS && numComponents > maxTfSeparateComponents) 282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; // Per-attribute component count exceeded. 283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project totalTfComponents += numComponents; 285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project totalTfAttribs += 1; 286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (tfMode == GL_SEPARATE_ATTRIBS && totalTfAttribs > maxTfSeparateAttribs) 289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (tfMode == GL_INTERLEAVED_ATTRIBS && totalTfComponents > maxTfInterleavedComponents) 292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// Program 298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 299e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic std::string getAttributeName (const char* varyingName, const glu::TypeComponentVector& path) 300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::ostringstream str; 302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project str << "a_" << (deStringBeginsWith(varyingName, "v_") ? varyingName+2 : varyingName); 304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (glu::TypeComponentVector::const_iterator iter = path.begin(); iter != path.end(); iter++) 306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char* prefix = DE_NULL; 308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (iter->type) 310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 311e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::VarTypeComponent::STRUCT_MEMBER: prefix = "_m"; break; 312e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::VarTypeComponent::ARRAY_ELEMENT: prefix = "_e"; break; 313e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::VarTypeComponent::MATRIX_COLUMN: prefix = "_c"; break; 314e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::VarTypeComponent::VECTOR_COMPONENT: prefix = "_s"; break; 315e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 316e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 317e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 318e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 319e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project str << prefix << iter->index; 320e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 321e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 322e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return str.str(); 323e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 324e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 325e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void genShaderSources (const ProgramSpec& spec, std::string& vertSource, std::string& fragSource, bool pointSizeRequired) 326e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 327e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::ostringstream vtx; 328e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::ostringstream frag; 329e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool addPointSize = spec.isPointSizeUsed(); 330e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 331e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "#version 300 es\n" 332e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << "in highp vec4 a_position;\n"; 333e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frag << "#version 300 es\n" 334e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << "layout(location = 0) out mediump vec4 o_color;\n" 335e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << "uniform highp vec4 u_scale;\n" 336e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << "uniform highp vec4 u_bias;\n"; 337e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 338e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (addPointSize) 339e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "in highp float a_pointSize;\n"; 340e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 341e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Declare attributes. 342e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Varying>::const_iterator var = spec.getVaryings().begin(); var != spec.getVaryings().end(); var++) 343e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 344e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char* name = var->name.c_str(); 345e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const glu::VarType& type = var->type; 346e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 347e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (glu::VectorTypeIterator vecIter = glu::VectorTypeIterator::begin(&type); vecIter != glu::VectorTypeIterator::end(&type); vecIter++) 348e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 349e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::VarType attribType = glu::getVarType(type, vecIter.getPath()); 350e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project string attribName = getAttributeName(name, vecIter.getPath()); 351e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 352e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "in " << glu::declare(attribType, attribName.c_str()) << ";\n"; 353e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 354e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 355e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 356e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Declare vayrings. 357e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int ndx = 0; ndx < 2; ndx++) 358e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 359e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char* inout = ndx ? "in" : "out"; 360e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::ostringstream& str = ndx ? frag : vtx; 361e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 362e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Declare structs that have type name. 363e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<glu::StructType*>::const_iterator structIter = spec.getStructs().begin(); structIter != spec.getStructs().end(); structIter++) 364e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 365e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const glu::StructType* structPtr = *structIter; 366e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (structPtr->hasTypeName()) 367e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project str << glu::declare(structPtr) << ";\n"; 368e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 369e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 370e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Varying>::const_iterator var = spec.getVaryings().begin(); var != spec.getVaryings().end(); var++) 371e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project str << getInterpolationName(var->interpolation) << " " << inout << " " << glu::declare(var->type, var->name.c_str()) << ";\n"; 372e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 373e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 374e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "\nvoid main (void)\n{\n" 375e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << "\tgl_Position = a_position;\n"; 376e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frag << "\nvoid main (void)\n{\n" 377e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << "\thighp vec4 res = vec4(0.0);\n"; 378c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu 379e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (addPointSize) 380e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "\tgl_PointSize = a_pointSize;\n"; 381e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (pointSizeRequired) 382e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "\tgl_PointSize = 1.0;\n"; 383e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 384e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Generate assignments / usage. 385e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Varying>::const_iterator var = spec.getVaryings().begin(); var != spec.getVaryings().end(); var++) 386e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 387e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char* name = var->name.c_str(); 388e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const glu::VarType& type = var->type; 389e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 390e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (glu::VectorTypeIterator vecIter = glu::VectorTypeIterator::begin(&type); vecIter != glu::VectorTypeIterator::end(&type); vecIter++) 391e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 392e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::VarType subType = glu::getVarType(type, vecIter.getPath()); 393e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project string attribName = getAttributeName(name, vecIter.getPath()); 394e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 395e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(subType.isBasicType() && glu::isDataTypeScalarOrVector(subType.getBasicType())); 396e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 397e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Vertex: assign from attribute. 398e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "\t" << name << vecIter << " = " << attribName << ";\n"; 399e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 400e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Fragment: add to res variable. 401e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int scalarSize = glu::getDataTypeScalarSize(subType.getBasicType()); 402e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 403e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frag << "\tres += "; 404e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (scalarSize == 1) frag << "vec4(" << name << vecIter << ")"; 405e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (scalarSize == 2) frag << "vec2(" << name << vecIter << ").xxyy"; 406e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (scalarSize == 3) frag << "vec3(" << name << vecIter << ").xyzx"; 407e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (scalarSize == 4) frag << "vec4(" << name << vecIter << ")"; 408e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 409e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frag << ";\n"; 410e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 411e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 412e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 413e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frag << "\to_color = res * u_scale + u_bias;\n"; 414e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 415e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vtx << "}\n"; 416e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frag << "}\n"; 417e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 418e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vertSource = vtx.str(); 419e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project fragSource = frag.str(); 420e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 421e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 422e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic glu::ShaderProgram* createVertexCaptureProgram (const glu::RenderContext& context, const ProgramSpec& spec, deUint32 bufferMode, deUint32 primitiveType) 423e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 424e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string vertSource, fragSource; 425e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 426e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project genShaderSources(spec, vertSource, fragSource, primitiveType == GL_POINTS /* Is point size required? */); 427e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 428e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return new glu::ShaderProgram(context, glu::ProgramSources() 429e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << glu::VertexSource(vertSource) 430e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << glu::FragmentSource(fragSource) 431e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << glu::TransformFeedbackVaryings<vector<string>::const_iterator>(spec.getTransformFeedbackVaryings().begin(), spec.getTransformFeedbackVaryings().end()) 432e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project << glu::TransformFeedbackMode(bufferMode)); 433e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 434e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 435e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// Helpers. 436e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 437e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void computeInputLayout (vector<Attribute>& attributes, int& inputStride, const vector<Varying>& varyings, bool usePointSize) 438e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 439e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project inputStride = 0; 440e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 441e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Add position. 442e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project attributes.push_back(Attribute("a_position", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), inputStride)); 443e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project inputStride += 4*sizeof(deUint32); 444e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 445e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (usePointSize) 446e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 447e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project attributes.push_back(Attribute("a_pointSize", glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), inputStride)); 448e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project inputStride += 1*sizeof(deUint32); 449e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 450e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 451e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Compute attribute vector. 452e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Varying>::const_iterator var = varyings.begin(); var != varyings.end(); var++) 453e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 454e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (glu::VectorTypeIterator vecIter = glu::VectorTypeIterator::begin(&var->type); vecIter != glu::VectorTypeIterator::end(&var->type); vecIter++) 455e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 456e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::VarType type = vecIter.getType(); 457e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project string name = getAttributeName(var->name.c_str(), vecIter.getPath()); 458e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 459e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project attributes.push_back(Attribute(name, type, inputStride)); 460e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project inputStride += glu::getDataTypeScalarSize(type.getBasicType())*sizeof(deUint32); 461e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 462e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 463e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 464e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 465e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void computeTransformFeedbackOutputs (vector<Output>& transformFeedbackOutputs, const vector<Attribute>& attributes, const vector<Varying>& varyings, const vector<string>& transformFeedbackVaryings, deUint32 bufferMode) 466e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 467e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int accumulatedSize = 0; 468e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 469e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project transformFeedbackOutputs.resize(transformFeedbackVaryings.size()); 470e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int varNdx = 0; varNdx < (int)transformFeedbackVaryings.size(); varNdx++) 471e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 472e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const string& name = transformFeedbackVaryings[varNdx]; 473e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int bufNdx = (bufferMode == GL_SEPARATE_ATTRIBS ? varNdx : 0); 474e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int offset = (bufferMode == GL_SEPARATE_ATTRIBS ? 0 : accumulatedSize); 475e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Output& output = transformFeedbackOutputs[varNdx]; 476e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 477e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.name = name; 478e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.bufferNdx = bufNdx; 479e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.offset = offset; 480e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 481e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (name == "gl_Position") 482e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 483e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const Attribute* posIn = &(*std::find_if(attributes.begin(), attributes.end(), AttributeNameEquals("a_position"))); 484e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.type = posIn->type; 485e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.inputs.push_back(posIn); 486e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 487e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (name == "gl_PointSize") 488e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 489e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const Attribute* sizeIn = &(*std::find_if(attributes.begin(), attributes.end(), AttributeNameEquals("a_pointSize"))); 490e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.type = sizeIn->type; 491e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.inputs.push_back(sizeIn); 492e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 493e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else 494e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 495e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project string varName = glu::parseVariableName(name.c_str()); 496e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const Varying& varying = *std::find_if(varyings.begin(), varyings.end(), VaryingNameEquals(varName)); 497e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::TypeComponentVector varPath; 498e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 499e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::parseTypePath(name.c_str(), varying.type, varPath); 500e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 501e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.type = glu::getVarType(varying.type, varPath); 502e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 503e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Add all vectorized attributes as inputs. 504e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (glu::VectorTypeIterator iter = glu::VectorTypeIterator::begin(&output.type); iter != glu::VectorTypeIterator::end(&output.type); iter++) 505e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 506e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Full path. 507e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::TypeComponentVector fullPath(varPath.size() + iter.getPath().size()); 508e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 509e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::copy(varPath.begin(), varPath.end(), fullPath.begin()); 510e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::copy(iter.getPath().begin(), iter.getPath().end(), fullPath.begin()+varPath.size()); 511e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 512e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project string attribName = getAttributeName(varName.c_str(), fullPath); 513e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const Attribute* attrib = &(*std::find_if(attributes.begin(), attributes.end(), AttributeNameEquals(attribName))); 514e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 515e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project output.inputs.push_back(attrib); 516e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 517e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 518e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 519e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project accumulatedSize += output.type.getScalarSize()*sizeof(deUint32); 520e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 521e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 522e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 523e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void genAttributeData (const Attribute& attrib, deUint8* basePtr, int stride, int numElements, de::Random& rnd) 524e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 525e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const int elementSize = (int)sizeof(deUint32); 526e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool isFloat = glu::isDataTypeFloatOrVec(attrib.type.getBasicType()); 527e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool isInt = glu::isDataTypeIntOrIVec(attrib.type.getBasicType()); 528e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool isUint = glu::isDataTypeIntOrIVec(attrib.type.getBasicType()); 529e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::Precision precision = attrib.type.getPrecision(); 530e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numComps = glu::getDataTypeScalarSize(attrib.type.getBasicType()); 531e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 532e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int elemNdx = 0; elemNdx < numElements; elemNdx++) 533c95c79ccb65d82a65b960919077d5c359cf28cedEvan Chu { 534e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int compNdx = 0; compNdx < numComps; compNdx++) 535e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 536e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int offset = attrib.offset+elemNdx*stride+compNdx*elementSize; 537e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (isFloat) 538e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 539e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project float* comp = (float*)(basePtr+offset); 540e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (precision) 541e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 542e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_LOWP: *comp = 0.0f + 0.25f*(float)rnd.getInt(0, 4); break; 543e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_MEDIUMP: *comp = rnd.getFloat(-1e3f, 1e3f); break; 544e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_HIGHP: *comp = rnd.getFloat(-1e5f, 1e5f); break; 545e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 546e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 547e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 548e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 549e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (isInt) 550e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 551e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int* comp = (int*)(basePtr+offset); 552e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (precision) 553e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 554e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_LOWP: *comp = (int)(rnd.getUint32()&0xff) << 24 >> 24; break; 555e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_MEDIUMP: *comp = (int)(rnd.getUint32()&0xffff) << 16 >> 16; break; 556e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_HIGHP: *comp = (int)rnd.getUint32(); break; 557e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 558e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 559e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 560e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 561e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (isUint) 562e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 563e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32* comp = (deUint32*)(basePtr+offset); 564e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (precision) 565e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 566e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_LOWP: *comp = rnd.getUint32()&0xff; break; 567e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_MEDIUMP: *comp = rnd.getUint32()&0xffff; break; 568e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_HIGHP: *comp = rnd.getUint32(); break; 569e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 570e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 571e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 572e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 573e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 574e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 575e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 576e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 577e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void genInputData (const vector<Attribute>& attributes, int numInputs, int inputStride, deUint8* inputBasePtr, de::Random& rnd) 578e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 579e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Random positions. 580e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const Attribute& position = *std::find_if(attributes.begin(), attributes.end(), AttributeNameEquals("a_position")); 581e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 582e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int ndx = 0; ndx < numInputs; ndx++) 583e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 584e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint8* ptr = inputBasePtr + position.offset + inputStride*ndx; 585e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *((float*)(ptr+ 0)) = rnd.getFloat(-1.2f, 1.2f); 586e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *((float*)(ptr+ 4)) = rnd.getFloat(-1.2f, 1.2f); 587e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *((float*)(ptr+ 8)) = rnd.getFloat(-1.2f, 1.2f); 588e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *((float*)(ptr+12)) = rnd.getFloat(0.1f, 2.0f); 589e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 590e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 591e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Point size. 592e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<Attribute>::const_iterator pointSizePos = std::find_if(attributes.begin(), attributes.end(), AttributeNameEquals("a_pointSize")); 593e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (pointSizePos != attributes.end()) 594e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 595e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int ndx = 0; ndx < numInputs; ndx++) 596e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 597e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint8* ptr = inputBasePtr + pointSizePos->offset + inputStride*ndx; 598e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *((float*)ptr) = rnd.getFloat(1.0f, 8.0f); 599e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 600e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 601e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 602e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Random data for rest of components. 603e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Attribute>::const_iterator attrib = attributes.begin(); attrib != attributes.end(); attrib++) 604e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 605e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (attrib->name == "a_position" || attrib->name == "a_pointSize") 606e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project continue; 607e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 608e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project genAttributeData(*attrib, inputBasePtr, inputStride, numInputs, rnd); 609e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 610e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 611e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 612e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic deUint32 getTransformFeedbackOutputCount (deUint32 primitiveType, int numElements) 613e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 614e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (primitiveType) 615e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 616e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLES: return numElements - numElements%3; 617e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLE_STRIP: return de::max(0, numElements-2)*3; 618e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLE_FAN: return de::max(0, numElements-2)*3; 619e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINES: return numElements - numElements%2; 620e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINE_STRIP: return de::max(0, numElements-1)*2; 621e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINE_LOOP: return numElements > 1 ? numElements*2 : 0; 622e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_POINTS: return numElements; 623e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 624e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 625e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 626e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return 0; 627e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 628e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 629e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 630e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic deUint32 getTransformFeedbackPrimitiveCount (deUint32 primitiveType, int numElements) 631e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 632e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (primitiveType) 633e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 634e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLES: return numElements/3; 635e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLE_STRIP: return de::max(0, numElements-2); 636e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLE_FAN: return de::max(0, numElements-2); 637e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINES: return numElements/2; 638e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINE_STRIP: return de::max(0, numElements-1); 639e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINE_LOOP: return numElements > 1 ? numElements : 0; 640e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_POINTS: return numElements; 641e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 642e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 643e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 644e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return 0; 645e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 646e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 647e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 648e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic deUint32 getTransformFeedbackPrimitiveMode (deUint32 primitiveType) 649e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 6505c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen switch (primitiveType) 6515c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen { 6525c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case GL_TRIANGLES: 6535c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case GL_TRIANGLE_STRIP: 6545c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case GL_TRIANGLE_FAN: 6555c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen return GL_TRIANGLES; 6565c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 6575c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case GL_LINES: 6585c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case GL_LINE_LOOP: 6595c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case GL_LINE_STRIP: 6605c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen return GL_LINES; 6615c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 6625c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen case GL_POINTS: 6635c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen return GL_POINTS; 6645c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 6655c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen default: 6665c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen DE_ASSERT(false); 6675c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen return 0; 668e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 669e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 670e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 671e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic int getAttributeIndex (deUint32 primitiveType, int numInputs, int outNdx) 672e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 673e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (primitiveType) 674e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 675e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLES: return outNdx; 676e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINES: return outNdx; 677e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_POINTS: return outNdx; 678e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 679e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLE_STRIP: 680e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 681e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int triNdx = outNdx/3; 682e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int vtxNdx = outNdx%3; 683e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return (triNdx%2 != 0 && vtxNdx < 2) ? (triNdx+1-vtxNdx) : (triNdx+vtxNdx); 684e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 685e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 686e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_TRIANGLE_FAN: 687e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return (outNdx%3 != 0) ? (outNdx/3 + outNdx%3) : 0; 688e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 689e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINE_STRIP: 690e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return outNdx/2 + outNdx%2; 691e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 692e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case GL_LINE_LOOP: 693e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 694e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int inNdx = outNdx/2 + outNdx%2; 695e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return inNdx < numInputs ? inNdx : 0; 696e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 697e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 698e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 699e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 700e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return 0; 701e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 702e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 703e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 704e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic bool compareTransformFeedbackOutput (tcu::TestLog& log, deUint32 primitiveType, const Output& output, int numInputs, const deUint8* inBasePtr, int inStride, const deUint8* outBasePtr, int outStride) 705e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 706e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool isOk = true; 707e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int outOffset = output.offset; 708e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 709e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int attrNdx = 0; attrNdx < (int)output.inputs.size(); attrNdx++) 710e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 711e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const Attribute& attribute = *output.inputs[attrNdx]; 712e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::DataType type = attribute.type.getBasicType(); 713e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numComponents = glu::getDataTypeScalarSize(type); 714e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::Precision precision = attribute.type.getPrecision(); 715e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::DataType scalarType = glu::getDataTypeScalarType(type); 716e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numOutputs = getTransformFeedbackOutputCount(primitiveType, numInputs); 717e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 718e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int outNdx = 0; outNdx < numOutputs; outNdx++) 719e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 720e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int inNdx = getAttributeIndex(primitiveType, numInputs, outNdx); 721e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 722e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int compNdx = 0; compNdx < numComponents; compNdx++) 723e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 724e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const deUint8* inPtr = inBasePtr + inStride*inNdx + attribute.offset + compNdx*sizeof(deUint32); 725e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const deUint8* outPtr = outBasePtr + outStride*outNdx + outOffset + compNdx*sizeof(deUint32); 726e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 inVal = *(const deUint32*)inPtr; 727e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 outVal = *(const deUint32*)outPtr; 728e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool isEqual = false; 729e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 730e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (scalarType == glu::TYPE_FLOAT) 731e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 732e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // ULP comparison is used for highp and mediump. Lowp uses threshold-comparison. 733e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (precision) 734e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 735e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_HIGHP: isEqual = de::abs((int)inVal - (int)outVal) < 2; break; 736e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_MEDIUMP: isEqual = de::abs((int)inVal - (int)outVal) < 2+(1<<13); break; 737e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case glu::PRECISION_LOWP: 738e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 739e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project float inF = *(const float*)inPtr; 740e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project float outF = *(const float*)outPtr; 741e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project isEqual = de::abs(inF - outF) < 0.1f; 742e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 743e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 744e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 745e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(false); 746e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 747e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 748e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else 749e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project isEqual = (inVal == outVal); // Bit-exact match required for integer types. 750e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 751e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!isEqual) 752e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 753e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "Mismatch in " << output.name << " (" << attribute.name << "), output = " << outNdx << ", input = " << inNdx << ", component = " << compNdx << TestLog::EndMessage; 754e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project isOk = false; 755e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 756e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 757e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 758e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 759e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!isOk) 760e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 761e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 762e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 763e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!isOk) 764e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 765e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 766e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project outOffset += numComponents*sizeof(deUint32); 767e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 768e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 769e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return isOk; 770e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 771e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 772e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic int computeTransformFeedbackPrimitiveCount (deUint32 primitiveType, const DrawCall* first, const DrawCall* end) 773e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 774e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int primCount = 0; 775e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 776e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (const DrawCall* call = first; call != end; ++call) 777e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 778e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (call->transformFeedbackEnabled) 779e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project primCount += getTransformFeedbackPrimitiveCount(primitiveType, call->numElements); 780e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 781e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 782e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return primCount; 783e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 784e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 785e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void writeBufferGuard (const glw::Functions& gl, deUint32 target, int bufferSize, int guardSize) 786e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 787e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint8* ptr = (deUint8*)gl.mapBufferRange(target, bufferSize, guardSize, GL_MAP_WRITE_BIT); 788e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (ptr) 789e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deMemset(ptr, 0xcd, guardSize); 790e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.unmapBuffer(target); 791e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "guardband write"); 792e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 793e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 794e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic bool verifyGuard (const deUint8* ptr, int guardSize) 795e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 796e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int ndx = 0; ndx < guardSize; ndx++) 797e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 798e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (ptr[ndx] != 0xcd) 799e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 800e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 801e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 802e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 803e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 804e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic void logTransformFeedbackVaryings (TestLog& log, const glw::Functions& gl, deUint32 program) 805e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 806e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numTfVaryings = 0; 807e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int maxNameLen = 0; 808e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 809e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYINGS, &numTfVaryings); 810e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getProgramiv(program, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &maxNameLen); 811e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "Query TF varyings"); 812e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 813e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "GL_TRANSFORM_FEEDBACK_VARYINGS = " << numTfVaryings << TestLog::EndMessage; 814e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 815e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<char> nameBuf(maxNameLen+1); 816e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 817e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int ndx = 0; ndx < numTfVaryings; ndx++) 818e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 819e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glw::GLsizei size = 0; 820e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glw::GLenum type = 0; 821e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 822e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getTransformFeedbackVarying(program, ndx, (glw::GLsizei)nameBuf.size(), DE_NULL, &size, &type, &nameBuf[0]); 823e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackVarying()"); 824e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 825e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const glu::DataType dataType = glu::getDataTypeFromGLType(type); 826e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const std::string typeName = dataType != glu::TYPE_LAST ? std::string(glu::getDataTypeName(dataType)) 827e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : (std::string("unknown(") + tcu::toHex(type).toString() + ")"); 828e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 829e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << (const char*)&nameBuf[0] << ": " << typeName << "[" << size << "]" << TestLog::EndMessage; 830e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 831e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 832e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 833e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectclass TransformFeedbackCase : public TestCase 834e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 835e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectpublic: 836e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TransformFeedbackCase (Context& context, const char* name, const char* desc, deUint32 bufferMode, deUint32 primitiveType); 837e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ~TransformFeedbackCase (void); 838e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 839e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project void init (void); 840e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project void deinit (void); 841e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project IterateResult iterate (void); 842e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 843e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectprotected: 844e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ProgramSpec m_progSpec; 845e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 m_bufferMode; 846e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 m_primitiveType; 847e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 848e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectprivate: 849e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TransformFeedbackCase (const TransformFeedbackCase& other); 850e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TransformFeedbackCase& operator= (const TransformFeedbackCase& other); 851e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 852e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool runTest (const DrawCall* first, const DrawCall* end, deUint32 seed); 853e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 854e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Derived from ProgramSpec in init() 855e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int m_inputStride; 856e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<Attribute> m_attributes; 857e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<Output> m_transformFeedbackOutputs; 858e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<int> m_bufferStrides; 859e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 860e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // GL state. 861e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::ShaderProgram* m_program; 862e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::TransformFeedback* m_transformFeedback; 863e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<deUint32> m_outputBuffers; 864e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 865e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int m_iterNdx; 866e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 867e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 868e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectTransformFeedbackCase::TransformFeedbackCase (Context& context, const char* name, const char* desc, deUint32 bufferMode, deUint32 primitiveType) 869e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : TestCase (context, name, desc) 870e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , m_bufferMode (bufferMode) 871e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , m_primitiveType (primitiveType) 872e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , m_inputStride (0) 873e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , m_program (DE_NULL) 874e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , m_transformFeedback (DE_NULL) 875e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project , m_iterNdx (0) 876e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 877e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 878e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 879e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectTransformFeedbackCase::~TransformFeedbackCase (void) 880e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 881e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TransformFeedbackCase::deinit(); 882e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 883e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 884e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic bool hasArraysInTFVaryings (const ProgramSpec& spec) 885e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 886e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<string>::const_iterator tfVar = spec.getTransformFeedbackVaryings().begin(); tfVar != spec.getTransformFeedbackVaryings().end(); ++tfVar) 887e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 888e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project string varName = glu::parseVariableName(tfVar->c_str()); 889e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<Varying>::const_iterator varIter = std::find_if(spec.getVaryings().begin(), spec.getVaryings().end(), VaryingNameEquals(varName)); 890e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 891e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (varName == "gl_Position" || varName == "gl_PointSize") 892e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project continue; 893e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 894e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(varIter != spec.getVaryings().end()); 895e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 896e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (varIter->type.isArrayType()) 897e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 898e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 899e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 900e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 901e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 902a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu 903e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid TransformFeedbackCase::init (void) 904e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 905e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TestLog& log = m_testCtx.getLog(); 906e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 907e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 908e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(!m_program); 909e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_program = createVertexCaptureProgram(m_context.getRenderContext(), m_progSpec, m_bufferMode, m_primitiveType); 910a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu 911e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << *m_program; 9125c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (!m_program->isOk()) 9135c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen { 9145c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen const bool linkFail = m_program->getShaderInfo(glu::SHADERTYPE_VERTEX).compileOk && 9155c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk && 9165c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen !m_program->getProgramInfo().linkOk; 9175c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 9185c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (linkFail) 9195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen { 9205c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (!isProgramSupported(gl, m_progSpec, m_bufferMode)) 9215c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen throw tcu::NotSupportedError("Implementation limits execeeded", "", __FILE__, __LINE__); 9225c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen else if (hasArraysInTFVaryings(m_progSpec)) 9235c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen throw tcu::NotSupportedError("Capturing arrays is not supported (undefined in specification)", "", __FILE__, __LINE__); 9245c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen else 9255c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen throw tcu::TestError("Link failed", "", __FILE__, __LINE__); 926e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 927e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else 928e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project throw tcu::TestError("Compile failed", "", __FILE__, __LINE__); 929e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 930e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 9315c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen log << TestLog::Message << "Transform feedback varyings: " << tcu::formatArray(m_progSpec.getTransformFeedbackVaryings().begin(), m_progSpec.getTransformFeedbackVaryings().end()) << TestLog::EndMessage; 932e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 933e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Print out transform feedback points reported by GL. 934e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "Transform feedback varyings reported by compiler:" << TestLog::EndMessage; 935e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project logTransformFeedbackVaryings(log, gl, m_program->getProgram()); 936e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 937e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Compute input specification. 938e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project computeInputLayout(m_attributes, m_inputStride, m_progSpec.getVaryings(), m_progSpec.isPointSizeUsed()); 939e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 940e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Build list of varyings used in transform feedback. 9415c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen computeTransformFeedbackOutputs(m_transformFeedbackOutputs, m_attributes, m_progSpec.getVaryings(), m_progSpec.getTransformFeedbackVaryings(), m_bufferMode); 942e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(!m_transformFeedbackOutputs.empty()); 943e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 944e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Buffer strides. 945e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(m_bufferStrides.empty()); 946e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (m_bufferMode == GL_SEPARATE_ATTRIBS) 947e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 948e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Output>::const_iterator outIter = m_transformFeedbackOutputs.begin(); outIter != m_transformFeedbackOutputs.end(); outIter++) 949e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_bufferStrides.push_back(outIter->type.getScalarSize()*sizeof(deUint32)); 950e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 951e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else 952e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 953e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int totalSize = 0; 954e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Output>::const_iterator outIter = m_transformFeedbackOutputs.begin(); outIter != m_transformFeedbackOutputs.end(); outIter++) 955e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project totalSize += outIter->type.getScalarSize()*sizeof(deUint32); 956e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 957e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_bufferStrides.push_back(totalSize); 958e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 959e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 960e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // \note Actual storage is allocated in iterate(). 961e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_outputBuffers.resize(m_bufferStrides.size()); 962e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.genBuffers((glw::GLsizei)m_outputBuffers.size(), &m_outputBuffers[0]); 963e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 964e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DE_ASSERT(!m_transformFeedback); 965e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_transformFeedback = new glu::TransformFeedback(m_context.getRenderContext()); 966e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 967e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "init"); 968e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 969e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_iterNdx = 0; 970e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 971e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 972e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 97385b7e84f6cc61506c94e98844cac9ce50bbbe9dcEvan Chuvoid TransformFeedbackCase::deinit (void) 974e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 975e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 976e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 977e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!m_outputBuffers.empty()) 978e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 979e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.deleteBuffers((glw::GLsizei)m_outputBuffers.size(), &m_outputBuffers[0]); 980e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_outputBuffers.clear(); 981e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 982e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 983e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project delete m_transformFeedback; 984e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_transformFeedback = DE_NULL; 985e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 986e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project delete m_program; 987e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_program = DE_NULL; 988e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 989e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Clean up state. 99085b7e84f6cc61506c94e98844cac9ce50bbbe9dcEvan Chu m_attributes.clear(); 99185b7e84f6cc61506c94e98844cac9ce50bbbe9dcEvan Chu m_transformFeedbackOutputs.clear(); 992e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_bufferStrides.clear(); 993e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_inputStride = 0; 994e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 995e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 996e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectTransformFeedbackCase::IterateResult TransformFeedbackCase::iterate (void) 997e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 998e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Test cases. 999e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_elemCount1[] = { DrawCall(1, true) }; 1000e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_elemCount2[] = { DrawCall(2, true) }; 1001e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_elemCount3[] = { DrawCall(3, true) }; 1002e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_elemCount4[] = { DrawCall(4, true) }; 1003e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_elemCount123[] = { DrawCall(123, true) }; 1004e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_basicPause1[] = { DrawCall(64, true), DrawCall(64, false), DrawCall(64, true) }; 1005e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_basicPause2[] = { DrawCall(13, true), DrawCall(5, true), DrawCall(17, false), DrawCall(3, true), DrawCall(7, false) }; 1006e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_startPaused[] = { DrawCall(123, false), DrawCall(123, true) }; 1007e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_random1[] = { DrawCall(65, true), DrawCall(135, false), DrawCall(74, true), DrawCall(16, false), DrawCall(226, false), DrawCall(9, true), DrawCall(174, false) }; 1008e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const DrawCall s_random2[] = { DrawCall(217, true), DrawCall(171, true), DrawCall(147, true), DrawCall(152, false), DrawCall(55, true) }; 1009e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1010e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static const struct 1011e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1012e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const DrawCall* calls; 1013e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numCalls; 1014e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } s_iterations[] = 1015e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1016e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#define ITER(ARR) { ARR, DE_LENGTH_OF_ARRAY(ARR) } 1017e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_elemCount1), 1018e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_elemCount2), 1019e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_elemCount3), 1020e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_elemCount4), 1021e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_elemCount123), 1022e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_basicPause1), 102385b7e84f6cc61506c94e98844cac9ce50bbbe9dcEvan Chu ITER(s_basicPause2), 1024e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_startPaused), 1025e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_random1), 1026e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ITER(s_random2) 1027e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#undef ITER 1028e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project }; 1029e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1030e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TestLog& log = m_testCtx.getLog(); 1031e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool isOk = true; 1032e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 seed = deStringHash(getName()) ^ deInt32Hash(m_iterNdx); 1033e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numIterations = DE_LENGTH_OF_ARRAY(s_iterations); 1034e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const DrawCall* first = s_iterations[m_iterNdx].calls; 1035e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const DrawCall* end = s_iterations[m_iterNdx].calls + s_iterations[m_iterNdx].numCalls; 1036e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1037e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string sectionName = std::string("Iteration") + de::toString(m_iterNdx+1); 1038e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string sectionDesc = std::string("Iteration ") + de::toString(m_iterNdx+1) + " / " + de::toString(numIterations); 1039e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tcu::ScopedLogSection section (log, sectionName, sectionDesc); 1040e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1041e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "Testing " << s_iterations[m_iterNdx].numCalls << " draw calls, (element count, TF state): " << tcu::formatArray(first, end) << TestLog::EndMessage; 1042e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1043e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project isOk = runTest(first, end, seed); 1044e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1045e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!isOk) 1046e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed"); 1047e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1048e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_iterNdx += 1; 1049e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return (isOk && m_iterNdx < numIterations) ? CONTINUE : STOP; 1050e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1051e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1052e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool TransformFeedbackCase::runTest (const DrawCall* first, const DrawCall* end, deUint32 seed) 1053e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 1054e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TestLog& log = m_testCtx.getLog(); 1055e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1056e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project de::Random rnd (seed); 1057e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numInputs = 0; //!< Sum of element counts in calls. 1058e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numOutputs = 0; //!< Sum of output counts for calls that have transform feedback enabled. 1059e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int width = m_context.getRenderContext().getRenderTarget().getWidth(); 1060e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int height = m_context.getRenderContext().getRenderTarget().getHeight(); 1061e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int viewportW = de::min((int)VIEWPORT_WIDTH, width); 1062e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int viewportH = de::min((int)VIEWPORT_HEIGHT, height); 1063e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int viewportX = rnd.getInt(0, width-viewportW); 1064e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int viewportY = rnd.getInt(0, height-viewportH); 1065e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tcu::Surface frameWithTf (viewportW, viewportH); 1066e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tcu::Surface frameWithoutTf (viewportW, viewportH); 1067e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::Query primitiveQuery (m_context.getRenderContext()); 1068e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool outputsOk = true; 1069e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool imagesOk = true; 1070e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool queryOk = true; 1071e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1072e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Compute totals. 1073e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (const DrawCall* call = first; call != end; call++) 1074e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1075e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project numInputs += call->numElements; 1076e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project numOutputs += call->transformFeedbackEnabled ? getTransformFeedbackOutputCount(m_primitiveType, call->numElements) : 0; 1077e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1078e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1079e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Input data. 1080e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project vector<deUint8> inputData(m_inputStride*numInputs); 1081e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project genInputData(m_attributes, numInputs, m_inputStride, &inputData[0], rnd); 1082e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1083e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transformFeedback->get()); 1084e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback()"); 1085e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1086e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Allocate storage for transform feedback output buffers and bind to targets. 1087e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int bufNdx = 0; bufNdx < (int)m_outputBuffers.size(); bufNdx++) 1088e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1089e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 buffer = m_outputBuffers[bufNdx]; 1090e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int stride = m_bufferStrides[bufNdx]; 1091e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int target = bufNdx; 1092e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int size = stride*numOutputs; 1093e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int guardSize = stride*BUFFER_GUARD_MULTIPLIER; 1094e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const deUint32 usage = GL_DYNAMIC_READ; 1095e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1096e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer); 1097e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, size+guardSize, DE_NULL, usage); 1098e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project writeBufferGuard(gl, GL_TRANSFORM_FEEDBACK_BUFFER, size, guardSize); 1099e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // \todo [2012-07-30 pyry] glBindBufferRange()? 1101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, target, buffer); 1102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "transform feedback buffer setup"); 1104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Setup attributes. 1107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Attribute>::const_iterator attrib = m_attributes.begin(); attrib != m_attributes.end(); attrib++) 1108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int loc = gl.getAttribLocation(m_program->getProgram(), attrib->name.c_str()); 1110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::DataType scalarType = glu::getDataTypeScalarType(attrib->type.getBasicType()); 1111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int numComponents = glu::getDataTypeScalarSize(attrib->type.getBasicType()); 1112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const void* ptr = &inputData[0] + attrib->offset; 1113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (loc >= 0) 1115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.enableVertexAttribArray(loc); 1117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (scalarType == glu::TYPE_FLOAT) gl.vertexAttribPointer (loc, numComponents, GL_FLOAT, GL_FALSE, m_inputStride, ptr); 1119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (scalarType == glu::TYPE_INT) gl.vertexAttribIPointer (loc, numComponents, GL_INT, m_inputStride, ptr); 1120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if (scalarType == glu::TYPE_UINT) gl.vertexAttribIPointer (loc, numComponents, GL_UNSIGNED_INT, m_inputStride, ptr); 1121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Setup viewport. 1125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.viewport(viewportX, viewportY, viewportW, viewportH); 1126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Setup program. 1128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.useProgram(m_program->getProgram()); 1129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.uniform4fv(gl.getUniformLocation(m_program->getProgram(), "u_scale"), 1, tcu::Vec4(0.01f).getPtr()); 1131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.uniform4fv(gl.getUniformLocation(m_program->getProgram(), "u_bias"), 1, tcu::Vec4(0.5f).getPtr()); 1132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Enable query. 1134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, *primitiveQuery); 1135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)"); 1136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Draw. 1138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int offset = 0; 1140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool tfEnabled = true; 1141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.clear(GL_COLOR_BUFFER_BIT); 1143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.beginTransformFeedback(getTransformFeedbackPrimitiveMode(m_primitiveType)); 1145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (const DrawCall* call = first; call != end; call++) 1147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Pause or resume transform feedback if necessary. 1149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (call->transformFeedbackEnabled != tfEnabled) 1150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (call->transformFeedbackEnabled) 1152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.resumeTransformFeedback(); 1153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else 1154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.pauseTransformFeedback(); 1155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tfEnabled = call->transformFeedbackEnabled; 1156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.drawArrays(m_primitiveType, offset, call->numElements); 1159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project offset += call->numElements; 1160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Resume feedback before finishing it. 1163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tfEnabled) 1164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.resumeTransformFeedback(); 1165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.endTransformFeedback(); 1167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "render"); 1168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); 1171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)"); 1172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Check and log query status right after submit 1174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 available = GL_FALSE; 117685b7e84f6cc61506c94e98844cac9ce50bbbe9dcEvan Chu gl.getQueryObjectuiv(*primitiveQuery, GL_QUERY_RESULT_AVAILABLE, &available); 1177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv()"); 1178e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1179e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN status after submit: " << (available != GL_FALSE ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage; 1180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Compare result buffers. 1183e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int bufferNdx = 0; bufferNdx < (int)m_outputBuffers.size(); bufferNdx++) 1184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 buffer = m_outputBuffers[bufferNdx]; 1186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int stride = m_bufferStrides[bufferNdx]; 1187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int size = stride*numOutputs; 1188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int guardSize = stride*BUFFER_GUARD_MULTIPLIER; 1189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const void* bufPtr = DE_NULL; 1190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Bind buffer for reading. 1192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer); 1193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bufPtr = gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, size+guardSize, GL_MAP_READ_BIT); 1194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "mapping buffer"); 1195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Verify all output variables that are written to this buffer. 1197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (vector<Output>::const_iterator out = m_transformFeedbackOutputs.begin(); out != m_transformFeedbackOutputs.end(); out++) 1198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (out->bufferNdx != bufferNdx) 1200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project continue; 1201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int inputOffset = 0; 1203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int outputOffset = 0; 1204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Process all draw calls and check ones with transform feedback enabled. 1206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (const DrawCall* call = first; call != end; call++) 1207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (call->transformFeedbackEnabled) 1209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const deUint8* inputPtr = &inputData[0] + inputOffset*m_inputStride; 1211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const deUint8* outputPtr = (const deUint8*)bufPtr + outputOffset*stride; 1212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!compareTransformFeedbackOutput(log, m_primitiveType, *out, call->numElements, inputPtr, m_inputStride, outputPtr, stride)) 1214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project outputsOk = false; 1216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 1217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project inputOffset += call->numElements; 1221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project outputOffset += call->transformFeedbackEnabled ? getTransformFeedbackOutputCount(m_primitiveType, call->numElements) : 0; 1222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Verify guardband. 1226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!verifyGuard((const deUint8*)bufPtr + size, guardSize)) 1227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "Error: Transform feedback buffer overrun detected" << TestLog::EndMessage; 1229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project outputsOk = false; 1230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 1233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Check status after mapping buffers. 1236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const bool mustBeReady = !m_outputBuffers.empty(); // Mapping buffer forces synchronization. 1238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const int expectedCount = computeTransformFeedbackPrimitiveCount(m_primitiveType, first, end); 1239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 available = GL_FALSE; 1240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project deUint32 numPrimitives = 0; 1241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getQueryObjectuiv(*primitiveQuery, GL_QUERY_RESULT_AVAILABLE, &available); 1243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.getQueryObjectuiv(*primitiveQuery, GL_QUERY_RESULT, &numPrimitives); 1244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "glGetQueryObjectuiv()"); 1245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!mustBeReady && available == GL_FALSE) 1247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "ERROR: GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN result not available after mapping buffers!" << TestLog::EndMessage; 1249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project queryOk = false; 1250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = " << numPrimitives << TestLog::EndMessage; 1253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if ((int)numPrimitives != expectedCount) 1255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project log << TestLog::Message << "ERROR: Expected " << expectedCount << " primitives!" << TestLog::EndMessage; 1257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project queryOk = false; 1258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Clear transform feedback state. 1262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); 1263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (int bufNdx = 0; bufNdx < (int)m_outputBuffers.size(); bufNdx++) 1264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, 0); 1266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.bindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, bufNdx, 0); 1267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Read back rendered image. 1270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, frameWithTf.getAccess()); 1271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Render without transform feedback. 1273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int offset = 0; 1275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.clear(GL_COLOR_BUFFER_BIT); 1277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (const DrawCall* call = first; call != end; call++) 1279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gl.drawArrays(m_primitiveType, offset, call->numElements); 1281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project offset += call->numElements; 1282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GLU_EXPECT_NO_ERROR(gl.getError(), "render"); 1285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, frameWithoutTf.getAccess()); 1286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Compare images with and without transform feedback. 1289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project imagesOk = tcu::pixelThresholdCompare(log, "Result", "Image comparison result", frameWithoutTf, frameWithTf, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_ON_ERROR); 1290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (imagesOk) 1292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_testCtx.getLog() << TestLog::Message << "Rendering result comparison between TF enabled and TF disabled passed." << TestLog::EndMessage; 1293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else 1294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_testCtx.getLog() << TestLog::Message << "ERROR: Rendering result comparison between TF enabled and TF disabled failed!" << TestLog::EndMessage; 1295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return outputsOk && imagesOk && queryOk; 1297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1299e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// Test cases. 1300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectclass PositionCase : public TransformFeedbackCase 1302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 1303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectpublic: 1304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project PositionCase (Context& context, const char* name, const char* desc, deUint32 bufferType, deUint32 primitiveType) 1305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : TransformFeedbackCase(context, name, desc, bufferType, primitiveType) 1306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 1307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project m_progSpec.addTransformFeedbackVarying("gl_Position"); 1308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 1310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1311class PointSizeCase : public TransformFeedbackCase 1312{ 1313public: 1314 PointSizeCase (Context& context, const char* name, const char* desc, deUint32 bufferType, deUint32 primitiveType) 1315 : TransformFeedbackCase(context, name, desc, bufferType, primitiveType) 1316 { 1317 m_progSpec.addTransformFeedbackVarying("gl_PointSize"); 1318 } 1319}; 1320 1321class BasicTypeCase : public TransformFeedbackCase 1322{ 1323public: 1324 BasicTypeCase (Context& context, const char* name, const char* desc, deUint32 bufferType, deUint32 primitiveType, glu::DataType type, glu::Precision precision, Interpolation interpolation) 1325 : TransformFeedbackCase(context, name, desc, bufferType, primitiveType) 1326 { 1327 m_progSpec.addVarying("v_varA", glu::VarType(type, precision), interpolation); 1328 m_progSpec.addVarying("v_varB", glu::VarType(type, precision), interpolation); 1329 1330 m_progSpec.addTransformFeedbackVarying("v_varA"); 1331 m_progSpec.addTransformFeedbackVarying("v_varB"); 1332 } 1333}; 1334 1335class BasicArrayCase : public TransformFeedbackCase 1336{ 1337public: 1338 BasicArrayCase (Context& context, const char* name, const char* desc, deUint32 bufferType, deUint32 primitiveType, glu::DataType type, glu::Precision precision, Interpolation interpolation) 1339 : TransformFeedbackCase(context, name, desc, bufferType, primitiveType) 1340 { 1341 if (glu::isDataTypeMatrix(type) || m_bufferMode == GL_SEPARATE_ATTRIBS) 1342 { 1343 // \note For matrix types we need to use reduced array sizes or otherwise we will exceed maximum attribute (16) 1344 // or transform feedback component count (64). 1345 // On separate attribs mode maximum component count per varying is 4. 1346 m_progSpec.addVarying("v_varA", glu::VarType(glu::VarType(type, precision), 1), interpolation); 1347 m_progSpec.addVarying("v_varB", glu::VarType(glu::VarType(type, precision), 2), interpolation); 1348 } 1349 else 1350 { 1351 m_progSpec.addVarying("v_varA", glu::VarType(glu::VarType(type, precision), 3), interpolation); 1352 m_progSpec.addVarying("v_varB", glu::VarType(glu::VarType(type, precision), 4), interpolation); 1353 } 1354 1355 m_progSpec.addTransformFeedbackVarying("v_varA"); 1356 m_progSpec.addTransformFeedbackVarying("v_varB"); 1357 } 1358}; 1359 1360class ArrayElementCase : public TransformFeedbackCase 1361{ 1362public: 1363 ArrayElementCase (Context& context, const char* name, const char* desc, deUint32 bufferType, deUint32 primitiveType, glu::DataType type, glu::Precision precision, Interpolation interpolation) 1364 : TransformFeedbackCase(context, name, desc, bufferType, primitiveType) 1365 { 1366 m_progSpec.addVarying("v_varA", glu::VarType(glu::VarType(type, precision), 3), interpolation); 1367 m_progSpec.addVarying("v_varB", glu::VarType(glu::VarType(type, precision), 4), interpolation); 1368 1369 m_progSpec.addTransformFeedbackVarying("v_varA[1]"); 1370 m_progSpec.addTransformFeedbackVarying("v_varB[0]"); 1371 m_progSpec.addTransformFeedbackVarying("v_varB[3]"); 1372 } 1373}; 1374 1375class RandomCase : public TransformFeedbackCase 1376{ 1377public: 1378 RandomCase (Context& context, const char* name, const char* desc, deUint32 bufferType, deUint32 primitiveType, deUint32 seed) 1379 : TransformFeedbackCase (context, name, desc, bufferType, primitiveType) 1380 , m_seed (seed) 1381 { 1382 } 1383 1384 void init (void) 1385 { 1386 // \note Hard-coded indices and hackery are used when indexing this, beware. 1387 static const glu::DataType typeCandidates[] = 1388 { 1389 glu::TYPE_FLOAT, 1390 glu::TYPE_FLOAT_VEC2, 1391 glu::TYPE_FLOAT_VEC3, 1392 glu::TYPE_FLOAT_VEC4, 1393 glu::TYPE_INT, 1394 glu::TYPE_INT_VEC2, 1395 glu::TYPE_INT_VEC3, 1396 glu::TYPE_INT_VEC4, 1397 glu::TYPE_UINT, 1398 glu::TYPE_UINT_VEC2, 1399 glu::TYPE_UINT_VEC3, 1400 glu::TYPE_UINT_VEC4, 1401 1402 glu::TYPE_FLOAT_MAT2, 1403 glu::TYPE_FLOAT_MAT2X3, 1404 glu::TYPE_FLOAT_MAT2X4, 1405 1406 glu::TYPE_FLOAT_MAT3X2, 1407 glu::TYPE_FLOAT_MAT3, 1408 glu::TYPE_FLOAT_MAT3X4, 1409 1410 glu::TYPE_FLOAT_MAT4X2, 1411 glu::TYPE_FLOAT_MAT4X3, 1412 glu::TYPE_FLOAT_MAT4 1413 }; 1414 1415 static const glu::Precision precisions[] = 1416 { 1417 glu::PRECISION_LOWP, 1418 glu::PRECISION_MEDIUMP, 1419 glu::PRECISION_HIGHP 1420 }; 1421 1422 static const Interpolation interpModes[] = 1423 { 1424 INTERPOLATION_FLAT, 1425 INTERPOLATION_SMOOTH, 1426 INTERPOLATION_CENTROID 1427 }; 1428 1429 const int maxAttributeVectors = 16; 1430// const int maxTransformFeedbackComponents = 64; // \note It is enough to limit attribute set size. 1431 bool isSeparateMode = m_bufferMode == GL_SEPARATE_ATTRIBS; 1432 int maxTransformFeedbackVars = isSeparateMode ? 4 : maxAttributeVectors; 1433 const float arrayWeight = 0.3f; 1434 const float positionWeight = 0.7f; 1435 const float pointSizeWeight = 0.1f; 1436 const float captureFullArrayWeight = 0.5f; 1437 1438 de::Random rnd (m_seed); 1439 bool usePosition = rnd.getFloat() < positionWeight; 1440 bool usePointSize = rnd.getFloat() < pointSizeWeight; 1441 int numAttribVectorsToUse = rnd.getInt(1, maxAttributeVectors - 1/*position*/ - (usePointSize ? 1 : 0)); 1442 1443 int numAttributeVectors = 0; 1444 int varNdx = 0; 1445 1446 // Generate varyings. 1447 while (numAttributeVectors < numAttribVectorsToUse) 1448 { 1449 int maxVecs = isSeparateMode ? de::min(2 /*at most 2*mat2*/, numAttribVectorsToUse-numAttributeVectors) : numAttribVectorsToUse-numAttributeVectors; 1450 const glu::DataType* begin = &typeCandidates[0]; 1451 const glu::DataType* end = begin + (maxVecs >= 4 ? 21 : 1452 maxVecs >= 3 ? 18 : 1453 maxVecs >= 2 ? (isSeparateMode ? 13 : 15) : 12); 1454 1455 glu::DataType type = rnd.choose<glu::DataType>(begin, end); 1456 glu::Precision precision = rnd.choose<glu::Precision>(&precisions[0], &precisions[0]+DE_LENGTH_OF_ARRAY(precisions)); 1457 Interpolation interp = glu::getDataTypeScalarType(type) == glu::TYPE_FLOAT 1458 ? rnd.choose<Interpolation>(&interpModes[0], &interpModes[0]+DE_LENGTH_OF_ARRAY(interpModes)) 1459 : INTERPOLATION_FLAT; 1460 int numVecs = glu::isDataTypeMatrix(type) ? glu::getDataTypeMatrixNumColumns(type) : 1; 1461 int numComps = glu::getDataTypeScalarSize(type); 1462 int maxArrayLen = de::max(1, isSeparateMode ? 4/numComps : maxVecs/numVecs); 1463 bool useArray = rnd.getFloat() < arrayWeight; 1464 int arrayLen = useArray ? rnd.getInt(1, maxArrayLen) : 1; 1465 std::string name = "v_var" + de::toString(varNdx); 1466 1467 if (useArray) 1468 m_progSpec.addVarying(name.c_str(), glu::VarType(glu::VarType(type, precision), arrayLen), interp); 1469 else 1470 m_progSpec.addVarying(name.c_str(), glu::VarType(type, precision), interp); 1471 1472 numAttributeVectors += arrayLen*numVecs; 1473 varNdx += 1; 1474 } 1475 1476 // Generate transform feedback candidate set. 1477 vector<string> tfCandidates; 1478 1479 if (usePosition) tfCandidates.push_back("gl_Position"); 1480 if (usePointSize) tfCandidates.push_back("gl_PointSize"); 1481 1482 for (int ndx = 0; ndx < varNdx /* num varyings */; ndx++) 1483 { 1484 const Varying& var = m_progSpec.getVaryings()[ndx]; 1485 1486 if (var.type.isArrayType()) 1487 { 1488 const bool captureFull = rnd.getFloat() < captureFullArrayWeight; 1489 1490 if (captureFull) 1491 tfCandidates.push_back(var.name); 1492 else 1493 { 1494 const int numElem = var.type.getArraySize(); 1495 for (int elemNdx = 0; elemNdx < numElem; elemNdx++) 1496 tfCandidates.push_back(var.name + "[" + de::toString(elemNdx) + "]"); 1497 } 1498 } 1499 else 1500 tfCandidates.push_back(var.name); 1501 } 1502 1503 // Pick random selection. 1504 vector<string> tfVaryings(de::min((int)tfCandidates.size(), maxTransformFeedbackVars)); 1505 rnd.choose(tfCandidates.begin(), tfCandidates.end(), tfVaryings.begin(), (int)tfVaryings.size()); 1506 rnd.shuffle(tfVaryings.begin(), tfVaryings.end()); 1507 1508 for (vector<string>::const_iterator var = tfVaryings.begin(); var != tfVaryings.end(); var++) 1509 m_progSpec.addTransformFeedbackVarying(var->c_str()); 1510 1511 TransformFeedbackCase::init(); 1512 } 1513 1514private: 1515 deUint32 m_seed; 1516}; 1517 1518} // TransformFeedback 1519 1520using namespace TransformFeedback; 1521 1522TransformFeedbackTests::TransformFeedbackTests (Context& context) 1523 : TestCaseGroup(context, "transform_feedback", "Transform feedback tests") 1524{ 1525} 1526 1527TransformFeedbackTests::~TransformFeedbackTests (void) 1528{ 1529} 1530 1531void TransformFeedbackTests::init (void) 1532{ 1533 static const struct 1534 { 1535 const char* name; 1536 deUint32 mode; 1537 } bufferModes[] = 1538 { 1539 { "separate", GL_SEPARATE_ATTRIBS }, 1540 { "interleaved", GL_INTERLEAVED_ATTRIBS } 1541 }; 1542 1543 static const struct 1544 { 1545 const char* name; 1546 deUint32 type; 1547 } primitiveTypes[] = 1548 { 1549 { "points", GL_POINTS }, 1550 { "lines", GL_LINES }, 1551 { "triangles", GL_TRIANGLES } 1552 1553 // Not supported by GLES3. 1554// { "line_strip", GL_LINE_STRIP }, 1555// { "line_loop", GL_LINE_LOOP }, 1556// { "triangle_fan", GL_TRIANGLE_FAN }, 1557// { "triangle_strip", GL_TRIANGLE_STRIP } 1558 }; 1559 1560 static const glu::DataType basicTypes[] = 1561 { 1562 glu::TYPE_FLOAT, 1563 glu::TYPE_FLOAT_VEC2, 1564 glu::TYPE_FLOAT_VEC3, 1565 glu::TYPE_FLOAT_VEC4, 1566 glu::TYPE_FLOAT_MAT2, 1567 glu::TYPE_FLOAT_MAT2X3, 1568 glu::TYPE_FLOAT_MAT2X4, 1569 glu::TYPE_FLOAT_MAT3X2, 1570 glu::TYPE_FLOAT_MAT3, 1571 glu::TYPE_FLOAT_MAT3X4, 1572 glu::TYPE_FLOAT_MAT4X2, 1573 glu::TYPE_FLOAT_MAT4X3, 1574 glu::TYPE_FLOAT_MAT4, 1575 glu::TYPE_INT, 1576 glu::TYPE_INT_VEC2, 1577 glu::TYPE_INT_VEC3, 1578 glu::TYPE_INT_VEC4, 1579 glu::TYPE_UINT, 1580 glu::TYPE_UINT_VEC2, 1581 glu::TYPE_UINT_VEC3, 1582 glu::TYPE_UINT_VEC4 1583 }; 1584 1585 static const glu::Precision precisions[] = 1586 { 1587 glu::PRECISION_LOWP, 1588 glu::PRECISION_MEDIUMP, 1589 glu::PRECISION_HIGHP 1590 }; 1591 1592 static const struct 1593 { 1594 const char* name; 1595 Interpolation interp; 1596 } interpModes[] = 1597 { 1598 { "smooth", INTERPOLATION_SMOOTH }, 1599 { "flat", INTERPOLATION_FLAT }, 1600 { "centroid", INTERPOLATION_CENTROID } 1601 }; 1602 1603 // .position 1604 { 1605 tcu::TestCaseGroup* positionGroup = new tcu::TestCaseGroup(m_testCtx, "position", "gl_Position capture using transform feedback"); 1606 addChild(positionGroup); 1607 1608 for (int primitiveType = 0; primitiveType < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveType++) 1609 { 1610 for (int bufferMode = 0; bufferMode < DE_LENGTH_OF_ARRAY(bufferModes); bufferMode++) 1611 { 1612 string name = string(primitiveTypes[primitiveType].name) + "_" + bufferModes[bufferMode].name; 1613 positionGroup->addChild(new PositionCase(m_context, name.c_str(), "", bufferModes[bufferMode].mode, primitiveTypes[primitiveType].type)); 1614 } 1615 } 1616 } 1617 1618 // .point_size 1619 { 1620 tcu::TestCaseGroup* pointSizeGroup = new tcu::TestCaseGroup(m_testCtx, "point_size", "gl_PointSize capture using transform feedback"); 1621 addChild(pointSizeGroup); 1622 1623 for (int primitiveType = 0; primitiveType < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveType++) 1624 { 1625 for (int bufferMode = 0; bufferMode < DE_LENGTH_OF_ARRAY(bufferModes); bufferMode++) 1626 { 1627 string name = string(primitiveTypes[primitiveType].name) + "_" + bufferModes[bufferMode].name; 1628 pointSizeGroup->addChild(new PointSizeCase(m_context, name.c_str(), "", bufferModes[bufferMode].mode, primitiveTypes[primitiveType].type)); 1629 } 1630 } 1631 } 1632 1633 // .basic_type 1634 { 1635 tcu::TestCaseGroup* basicTypeGroup = new tcu::TestCaseGroup(m_testCtx, "basic_types", "Basic types in transform feedback"); 1636 addChild(basicTypeGroup); 1637 1638 for (int bufferModeNdx = 0; bufferModeNdx < DE_LENGTH_OF_ARRAY(bufferModes); bufferModeNdx++) 1639 { 1640 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[bufferModeNdx].name, ""); 1641 deUint32 bufferMode = bufferModes[bufferModeNdx].mode; 1642 basicTypeGroup->addChild(modeGroup); 1643 1644 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveTypeNdx++) 1645 { 1646 tcu::TestCaseGroup* primitiveGroup = new tcu::TestCaseGroup(m_testCtx, primitiveTypes[primitiveTypeNdx].name, ""); 1647 deUint32 primitiveType = primitiveTypes[primitiveTypeNdx].type; 1648 modeGroup->addChild(primitiveGroup); 1649 1650 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(basicTypes); typeNdx++) 1651 { 1652 glu::DataType type = basicTypes[typeNdx]; 1653 bool isFloat = glu::getDataTypeScalarType(type) == glu::TYPE_FLOAT; 1654 1655 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++) 1656 { 1657 glu::Precision precision = precisions[precNdx]; 1658 1659 string name = string(glu::getPrecisionName(precision)) + "_" + glu::getDataTypeName(type); 1660 primitiveGroup->addChild(new BasicTypeCase(m_context, name.c_str(), "", bufferMode, primitiveType, type, precision, isFloat ? INTERPOLATION_SMOOTH : INTERPOLATION_FLAT)); 1661 } 1662 } 1663 } 1664 } 1665 } 1666 1667 // .array 1668 { 1669 tcu::TestCaseGroup* arrayGroup = new tcu::TestCaseGroup(m_testCtx, "array", "Capturing whole array in TF"); 1670 addChild(arrayGroup); 1671 1672 for (int bufferModeNdx = 0; bufferModeNdx < DE_LENGTH_OF_ARRAY(bufferModes); bufferModeNdx++) 1673 { 1674 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[bufferModeNdx].name, ""); 1675 deUint32 bufferMode = bufferModes[bufferModeNdx].mode; 1676 arrayGroup->addChild(modeGroup); 1677 1678 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveTypeNdx++) 1679 { 1680 tcu::TestCaseGroup* primitiveGroup = new tcu::TestCaseGroup(m_testCtx, primitiveTypes[primitiveTypeNdx].name, ""); 1681 deUint32 primitiveType = primitiveTypes[primitiveTypeNdx].type; 1682 modeGroup->addChild(primitiveGroup); 1683 1684 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(basicTypes); typeNdx++) 1685 { 1686 glu::DataType type = basicTypes[typeNdx]; 1687 bool isFloat = glu::getDataTypeScalarType(type) == glu::TYPE_FLOAT; 1688 1689 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++) 1690 { 1691 glu::Precision precision = precisions[precNdx]; 1692 1693 string name = string(glu::getPrecisionName(precision)) + "_" + glu::getDataTypeName(type); 1694 primitiveGroup->addChild(new BasicArrayCase(m_context, name.c_str(), "", bufferMode, primitiveType, type, precision, isFloat ? INTERPOLATION_SMOOTH : INTERPOLATION_FLAT)); 1695 } 1696 } 1697 } 1698 } 1699 } 1700 1701 // .array_element 1702 { 1703 tcu::TestCaseGroup* arrayElemGroup = new tcu::TestCaseGroup(m_testCtx, "array_element", "Capturing single array element in TF"); 1704 addChild(arrayElemGroup); 1705 1706 for (int bufferModeNdx = 0; bufferModeNdx < DE_LENGTH_OF_ARRAY(bufferModes); bufferModeNdx++) 1707 { 1708 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[bufferModeNdx].name, ""); 1709 deUint32 bufferMode = bufferModes[bufferModeNdx].mode; 1710 arrayElemGroup->addChild(modeGroup); 1711 1712 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveTypeNdx++) 1713 { 1714 tcu::TestCaseGroup* primitiveGroup = new tcu::TestCaseGroup(m_testCtx, primitiveTypes[primitiveTypeNdx].name, ""); 1715 deUint32 primitiveType = primitiveTypes[primitiveTypeNdx].type; 1716 modeGroup->addChild(primitiveGroup); 1717 1718 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(basicTypes); typeNdx++) 1719 { 1720 glu::DataType type = basicTypes[typeNdx]; 1721 bool isFloat = glu::getDataTypeScalarType(type) == glu::TYPE_FLOAT; 1722 1723 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++) 1724 { 1725 glu::Precision precision = precisions[precNdx]; 1726 1727 string name = string(glu::getPrecisionName(precision)) + "_" + glu::getDataTypeName(type); 1728 primitiveGroup->addChild(new ArrayElementCase(m_context, name.c_str(), "", bufferMode, primitiveType, type, precision, isFloat ? INTERPOLATION_SMOOTH : INTERPOLATION_FLAT)); 1729 } 1730 } 1731 } 1732 } 1733 } 1734 1735 // .interpolation 1736 { 1737 tcu::TestCaseGroup* interpolationGroup = new tcu::TestCaseGroup(m_testCtx, "interpolation", "Different interpolation modes in transform feedback varyings"); 1738 addChild(interpolationGroup); 1739 1740 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(interpModes); modeNdx++) 1741 { 1742 Interpolation interp = interpModes[modeNdx].interp; 1743 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, interpModes[modeNdx].name, ""); 1744 1745 interpolationGroup->addChild(modeGroup); 1746 1747 for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++) 1748 { 1749 glu::Precision precision = precisions[precNdx]; 1750 1751 for (int primitiveType = 0; primitiveType < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveType++) 1752 { 1753 for (int bufferMode = 0; bufferMode < DE_LENGTH_OF_ARRAY(bufferModes); bufferMode++) 1754 { 1755 string name = string(glu::getPrecisionName(precision)) + "_vec4_" + primitiveTypes[primitiveType].name + "_" + bufferModes[bufferMode].name; 1756 modeGroup->addChild(new BasicTypeCase(m_context, name.c_str(), "", bufferModes[bufferMode].mode, primitiveTypes[primitiveType].type, glu::TYPE_FLOAT_VEC4, precision, interp)); 1757 } 1758 } 1759 } 1760 } 1761 } 1762 1763 // .random 1764 { 1765 tcu::TestCaseGroup* randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Randomized transform feedback cases"); 1766 addChild(randomGroup); 1767 1768 for (int bufferModeNdx = 0; bufferModeNdx < DE_LENGTH_OF_ARRAY(bufferModes); bufferModeNdx++) 1769 { 1770 tcu::TestCaseGroup* modeGroup = new tcu::TestCaseGroup(m_testCtx, bufferModes[bufferModeNdx].name, ""); 1771 deUint32 bufferMode = bufferModes[bufferModeNdx].mode; 1772 randomGroup->addChild(modeGroup); 1773 1774 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); primitiveTypeNdx++) 1775 { 1776 tcu::TestCaseGroup* primitiveGroup = new tcu::TestCaseGroup(m_testCtx, primitiveTypes[primitiveTypeNdx].name, ""); 1777 deUint32 primitiveType = primitiveTypes[primitiveTypeNdx].type; 1778 modeGroup->addChild(primitiveGroup); 1779 1780 for (int ndx = 0; ndx < 10; ndx++) 1781 { 1782 deUint32 seed = deInt32Hash(bufferMode) ^ deInt32Hash(primitiveType) ^ deInt32Hash(ndx); 1783 primitiveGroup->addChild(new RandomCase(m_context, de::toString(ndx+1).c_str(), "", bufferMode, primitiveType, seed)); 1784 } 1785 } 1786 } 1787 } 1788} 1789 1790} // Functional 1791} // gles3 1792} // deqp 1793