1#ifndef _GLSVERTEXARRAYTESTS_HPP 2#define _GLSVERTEXARRAYTESTS_HPP 3/*------------------------------------------------------------------------- 4 * drawElements Quality Program OpenGL (ES) Module 5 * ----------------------------------------------- 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Vertex array and buffer tests 24 *//*--------------------------------------------------------------------*/ 25 26#include "tcuTestCase.hpp" 27#include "tcuVector.hpp" 28#include "tcuSurface.hpp" 29#include "gluRenderContext.hpp" 30#include "gluCallLogWrapper.hpp" 31#include "tcuTestLog.hpp" 32#include "gluShaderProgram.hpp" 33#include "deFloat16.h" 34#include "tcuFloat.hpp" 35#include "tcuPixelFormat.hpp" 36#include "sglrContext.hpp" 37 38namespace sglr 39{ 40 41class ReferenceContextBuffers; 42class ReferenceContext; 43class Context; 44 45} // sglr 46 47namespace deqp 48{ 49namespace gls 50{ 51 52class Array 53{ 54public: 55 enum Target 56 { 57 // \note [mika] Are these actualy used somewhere? 58 TARGET_ELEMENT_ARRAY = 0, 59 TARGET_ARRAY, 60 61 TARGET_LAST 62 }; 63 64 enum InputType 65 { 66 INPUTTYPE_FLOAT = 0, 67 INPUTTYPE_FIXED, 68 INPUTTYPE_DOUBLE, 69 70 INPUTTYPE_BYTE, 71 INPUTTYPE_SHORT, 72 73 INPUTTYPE_UNSIGNED_BYTE, 74 INPUTTYPE_UNSIGNED_SHORT, 75 76 INPUTTYPE_INT, 77 INPUTTYPE_UNSIGNED_INT, 78 INPUTTYPE_HALF, 79 INPUTTYPE_UNSIGNED_INT_2_10_10_10, 80 INPUTTYPE_INT_2_10_10_10, 81 82 INPUTTYPE_LAST 83 }; 84 85 enum OutputType 86 { 87 OUTPUTTYPE_FLOAT = 0, 88 OUTPUTTYPE_VEC2, 89 OUTPUTTYPE_VEC3, 90 OUTPUTTYPE_VEC4, 91 92 OUTPUTTYPE_INT, 93 OUTPUTTYPE_UINT, 94 95 OUTPUTTYPE_IVEC2, 96 OUTPUTTYPE_IVEC3, 97 OUTPUTTYPE_IVEC4, 98 99 OUTPUTTYPE_UVEC2, 100 OUTPUTTYPE_UVEC3, 101 OUTPUTTYPE_UVEC4, 102 103 OUTPUTTYPE_LAST 104 }; 105 106 enum Usage 107 { 108 USAGE_DYNAMIC_DRAW = 0, 109 USAGE_STATIC_DRAW, 110 USAGE_STREAM_DRAW, 111 112 USAGE_STREAM_READ, 113 USAGE_STREAM_COPY, 114 115 USAGE_STATIC_READ, 116 USAGE_STATIC_COPY, 117 118 USAGE_DYNAMIC_READ, 119 USAGE_DYNAMIC_COPY, 120 121 USAGE_LAST 122 }; 123 124 enum Storage 125 { 126 STORAGE_USER = 0, 127 STORAGE_BUFFER, 128 129 STORAGE_LAST 130 }; 131 132 enum Primitive 133 { 134 PRIMITIVE_POINTS = 0, 135 PRIMITIVE_TRIANGLES, 136 PRIMITIVE_TRIANGLE_FAN, 137 PRIMITIVE_TRIANGLE_STRIP, 138 139 PRIMITIVE_LAST 140 }; 141 142 static std::string targetToString (Target target); 143 static std::string inputTypeToString (InputType type); 144 static std::string outputTypeToString (OutputType type); 145 static std::string usageTypeToString (Usage usage); 146 static std::string storageToString (Storage storage); 147 static std::string primitiveToString (Primitive primitive); 148 static int inputTypeSize (InputType type); 149 150 virtual ~Array (void) {} 151 virtual void data (Target target, int size, const char* data, Usage usage) = 0; 152 virtual void subdata (Target target, int offset, int size, const char* data) = 0; 153 virtual void bind (int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized, int stride) = 0; 154 virtual void unBind (void) = 0; 155 156 virtual bool isBound (void) const = 0; 157 virtual int getComponentCount (void) const = 0; 158 virtual Target getTarget (void) const = 0; 159 virtual InputType getInputType (void) const = 0; 160 virtual OutputType getOutputType (void) const = 0; 161 virtual Storage getStorageType (void) const = 0; 162 virtual bool getNormalized (void) const = 0; 163 virtual int getStride (void) const = 0; 164 virtual int getAttribNdx (void) const = 0; 165 virtual void setAttribNdx (int attribNdx) = 0; 166}; 167 168class ContextArray : public Array 169{ 170public: 171 ContextArray (Storage storage, sglr::Context& context); 172 virtual ~ContextArray (void); 173 virtual void data (Target target, int size, const char* data, Usage usage); 174 virtual void subdata (Target target, int offset, int size, const char* data); 175 virtual void bind (int attribNdx, int offset, int size, InputType inType, OutputType outType, bool normalized, int stride); 176 virtual void bindIndexArray (Array::Target storage); 177 virtual void unBind (void) { m_bound = false; } 178 virtual bool isBound (void) const { return m_bound; } 179 180 virtual int getComponentCount (void) const { return m_componentCount; } 181 virtual Array::Target getTarget (void) const { return m_target; } 182 virtual Array::InputType getInputType (void) const { return m_inputType; } 183 virtual Array::OutputType getOutputType (void) const { return m_outputType; } 184 virtual Array::Storage getStorageType (void) const { return m_storage; } 185 virtual bool getNormalized (void) const { return m_normalize; } 186 virtual int getStride (void) const { return m_stride; } 187 virtual int getAttribNdx (void) const { return m_attribNdx; } 188 virtual void setAttribNdx (int attribNdx) { m_attribNdx = attribNdx; } 189 190 void glBind (deUint32 loc); 191 static deUint32 targetToGL (Array::Target target); 192 static deUint32 usageToGL (Array::Usage usage); 193 static deUint32 inputTypeToGL (Array::InputType type); 194 static std::string outputTypeToGLType (Array::OutputType type); 195 static deUint32 primitiveToGL (Array::Primitive primitive); 196 197private: 198 Storage m_storage; 199 sglr::Context& m_ctx; 200 deUint32 m_glBuffer; 201 202 bool m_bound; 203 int m_attribNdx; 204 int m_size; 205 char* m_data; 206 int m_componentCount; 207 Array::Target m_target; 208 Array::InputType m_inputType; 209 Array::OutputType m_outputType; 210 bool m_normalize; 211 int m_stride; 212 int m_offset; 213}; 214 215class ContextArrayPack 216{ 217public: 218 ContextArrayPack (glu::RenderContext& renderCtx, sglr::Context& drawContext); 219 virtual ~ContextArrayPack (void); 220 virtual Array* getArray (int i); 221 virtual int getArrayCount (void); 222 virtual void newArray (Array::Storage storage); 223 virtual void render (Array::Primitive primitive, int firstVertex, int vertexCount, bool useVao, float coordScale, float colorScale); 224 225 const tcu::Surface& getSurface (void) const { return m_screen; } 226private: 227 void updateProgram (void); 228 glu::RenderContext& m_renderCtx; 229 sglr::Context& m_ctx; 230 231 std::vector<ContextArray*> m_arrays; 232 sglr::ShaderProgram* m_program; 233 tcu::Surface m_screen; 234}; 235 236class GLValue 237{ 238public: 239 240 template<class Type> 241 class WrappedType 242 { 243 public: 244 static WrappedType<Type> create (Type value) { WrappedType<Type> v; v.m_value = value; return v; } 245 inline Type getValue (void) const { return m_value; } 246 247 inline WrappedType<Type> operator+ (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value + other.getValue()); } 248 inline WrappedType<Type> operator* (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value * other.getValue()); } 249 inline WrappedType<Type> operator/ (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value / other.getValue()); } 250 inline WrappedType<Type> operator- (const WrappedType<Type>& other) const { return WrappedType<Type>::create(m_value - other.getValue()); } 251 252 inline WrappedType<Type>& operator+= (const WrappedType<Type>& other) { m_value += other.getValue(); return *this; } 253 inline WrappedType<Type>& operator*= (const WrappedType<Type>& other) { m_value *= other.getValue(); return *this; } 254 inline WrappedType<Type>& operator/= (const WrappedType<Type>& other) { m_value /= other.getValue(); return *this; } 255 inline WrappedType<Type>& operator-= (const WrappedType<Type>& other) { m_value -= other.getValue(); return *this; } 256 257 inline bool operator== (const WrappedType<Type>& other) const { return m_value == other.m_value; } 258 inline bool operator!= (const WrappedType<Type>& other) const { return m_value != other.m_value; } 259 inline bool operator< (const WrappedType<Type>& other) const { return m_value < other.m_value; } 260 inline bool operator> (const WrappedType<Type>& other) const { return m_value > other.m_value; } 261 inline bool operator<= (const WrappedType<Type>& other) const { return m_value <= other.m_value; } 262 inline bool operator>= (const WrappedType<Type>& other) const { return m_value >= other.m_value; } 263 264 inline operator Type (void) const { return m_value; } 265 template<class T> 266 inline T to (void) const { return (T)m_value; } 267 private: 268 Type m_value; 269 }; 270 271 typedef WrappedType<deInt16> Short; 272 typedef WrappedType<deUint16> Ushort; 273 274 typedef WrappedType<deInt8> Byte; 275 typedef WrappedType<deUint8> Ubyte; 276 277 typedef WrappedType<float> Float; 278 typedef WrappedType<double> Double; 279 280 typedef WrappedType<deInt32> Int; 281 typedef WrappedType<deUint32> Uint; 282 283 class Half 284 { 285 public: 286 static Half create (float value) { Half h; h.m_value = floatToHalf(value); return h; } 287 inline deFloat16 getValue (void) const { return m_value; } 288 289 inline Half operator+ (const Half& other) const { return create(halfToFloat(m_value) + halfToFloat(other.getValue())); } 290 inline Half operator* (const Half& other) const { return create(halfToFloat(m_value) * halfToFloat(other.getValue())); } 291 inline Half operator/ (const Half& other) const { return create(halfToFloat(m_value) / halfToFloat(other.getValue())); } 292 inline Half operator- (const Half& other) const { return create(halfToFloat(m_value) - halfToFloat(other.getValue())); } 293 294 inline Half& operator+= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; } 295 inline Half& operator*= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) * halfToFloat(m_value)); return *this; } 296 inline Half& operator/= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) / halfToFloat(m_value)); return *this; } 297 inline Half& operator-= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) - halfToFloat(m_value)); return *this; } 298 299 inline bool operator== (const Half& other) const { return m_value == other.m_value; } 300 inline bool operator!= (const Half& other) const { return m_value != other.m_value; } 301 inline bool operator< (const Half& other) const { return halfToFloat(m_value) < halfToFloat(other.m_value); } 302 inline bool operator> (const Half& other) const { return halfToFloat(m_value) > halfToFloat(other.m_value); } 303 inline bool operator<= (const Half& other) const { return halfToFloat(m_value) <= halfToFloat(other.m_value); } 304 inline bool operator>= (const Half& other) const { return halfToFloat(m_value) >= halfToFloat(other.m_value); } 305 306 template<class T> 307 inline T to (void) const { return (T)halfToFloat(m_value); } 308 309 inline static deFloat16 floatToHalf (float f); 310 inline static float halfToFloat (deFloat16 h); 311 private: 312 deFloat16 m_value; 313 }; 314 315 class Fixed 316 { 317 public: 318 static Fixed create (deInt32 value) { Fixed v; v.m_value = value; return v; } 319 inline deInt32 getValue (void) const { return m_value; } 320 321 inline Fixed operator+ (const Fixed& other) const { return create(m_value + other.getValue()); } 322 inline Fixed operator* (const Fixed& other) const { return create(m_value * other.getValue()); } 323 inline Fixed operator/ (const Fixed& other) const { return create(m_value / other.getValue()); } 324 inline Fixed operator- (const Fixed& other) const { return create(m_value - other.getValue()); } 325 326 inline Fixed& operator+= (const Fixed& other) { m_value += other.getValue(); return *this; } 327 inline Fixed& operator*= (const Fixed& other) { m_value *= other.getValue(); return *this; } 328 inline Fixed& operator/= (const Fixed& other) { m_value /= other.getValue(); return *this; } 329 inline Fixed& operator-= (const Fixed& other) { m_value -= other.getValue(); return *this; } 330 331 inline bool operator== (const Fixed& other) const { return m_value == other.m_value; } 332 inline bool operator!= (const Fixed& other) const { return m_value != other.m_value; } 333 inline bool operator< (const Fixed& other) const { return m_value < other.m_value; } 334 inline bool operator> (const Fixed& other) const { return m_value > other.m_value; } 335 inline bool operator<= (const Fixed& other) const { return m_value <= other.m_value; } 336 inline bool operator>= (const Fixed& other) const { return m_value >= other.m_value; } 337 338 inline operator deInt32 (void) const { return m_value; } 339 template<class T> 340 inline T to (void) const { return (T)m_value; } 341 private: 342 deInt32 m_value; 343 }; 344 345 // \todo [mika] This is pretty messy 346 GLValue (void) : type(Array::INPUTTYPE_LAST) {} 347 explicit GLValue (Float value) : type(Array::INPUTTYPE_FLOAT), fl(value) {} 348 explicit GLValue (Fixed value) : type(Array::INPUTTYPE_FIXED), fi(value) {} 349 explicit GLValue (Byte value) : type(Array::INPUTTYPE_BYTE), b(value) {} 350 explicit GLValue (Ubyte value) : type(Array::INPUTTYPE_UNSIGNED_BYTE), ub(value) {} 351 explicit GLValue (Short value) : type(Array::INPUTTYPE_SHORT), s(value) {} 352 explicit GLValue (Ushort value) : type(Array::INPUTTYPE_UNSIGNED_SHORT), us(value) {} 353 explicit GLValue (Int value) : type(Array::INPUTTYPE_INT), i(value) {} 354 explicit GLValue (Uint value) : type(Array::INPUTTYPE_UNSIGNED_INT), ui(value) {} 355 explicit GLValue (Half value) : type(Array::INPUTTYPE_HALF), h(value) {} 356 explicit GLValue (Double value) : type(Array::INPUTTYPE_DOUBLE), d(value) {} 357 358 float toFloat (void) const; 359 360 static GLValue getMaxValue (Array::InputType type); 361 static GLValue getMinValue (Array::InputType type); 362 363 Array::InputType type; 364 365 union 366 { 367 Float fl; 368 Fixed fi; 369 Double d; 370 Byte b; 371 Ubyte ub; 372 Short s; 373 Ushort us; 374 Int i; 375 Uint ui; 376 Half h; 377 }; 378}; 379 380class VertexArrayTest : public tcu::TestCase 381{ 382public: 383 VertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name ,const char* desc); 384 virtual ~VertexArrayTest (void); 385 virtual void init (void); 386 virtual void deinit (void); 387 388protected: 389 VertexArrayTest (const VertexArrayTest& other); 390 VertexArrayTest& operator= (const VertexArrayTest& other); 391 392 void compare (void); 393 394 glu::RenderContext& m_renderCtx; 395 396 sglr::ReferenceContextBuffers* m_refBuffers; 397 sglr::ReferenceContext* m_refContext; 398 sglr::Context* m_glesContext; 399 400 ContextArrayPack* m_glArrayPack; 401 ContextArrayPack* m_rrArrayPack; 402 bool m_isOk; 403 404 int m_maxDiffRed; 405 int m_maxDiffGreen; 406 int m_maxDiffBlue; 407}; 408 409class MultiVertexArrayTest : public VertexArrayTest 410{ 411public: 412 class Spec 413 { 414 public: 415 class ArraySpec 416 { 417 public: 418 ArraySpec (Array::InputType inputType, Array::OutputType outputType, Array::Storage storage, Array::Usage usage, int componetCount, int offset, int stride, bool normalize, GLValue min, GLValue max); 419 420 Array::InputType inputType; 421 Array::OutputType outputType; 422 Array::Storage storage; 423 Array::Usage usage; 424 int componentCount; 425 int offset; 426 int stride; 427 bool normalize; 428 GLValue min; 429 GLValue max; 430 }; 431 432 std::string getName (void) const; 433 std::string getDesc (void) const; 434 435 Array::Primitive primitive; 436 int drawCount; //!<Number of primitives to draw 437 int first; 438 439 std::vector<ArraySpec> arrays; 440 }; 441 442 MultiVertexArrayTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const Spec& spec, const char* name, const char* desc); 443 virtual ~MultiVertexArrayTest (void); 444 virtual IterateResult iterate (void); 445 446private: 447 bool isUnalignedBufferOffsetTest (void) const; 448 bool isUnalignedBufferStrideTest (void) const; 449 450 Spec m_spec; 451 int m_iteration; 452}; 453 454inline deFloat16 GLValue::Half::floatToHalf (float f) 455{ 456 // No denorm support. 457 tcu::Float<deUint16, 5, 10, 15, tcu::FLOAT_HAS_SIGN> v(f); 458 DE_ASSERT(!v.isNaN() && !v.isInf()); 459 return v.bits(); 460} 461 462inline float GLValue::Half::halfToFloat (deFloat16 h) 463{ 464 return tcu::Float16((deUint16)h).asFloat(); 465} 466 467} // gls 468} // deqp 469 470#endif // _GLSVERTEXARRAYTESTS_HPP 471