1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2016 Google Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2016 The Khronos Group Inc. 7e5c31af7Sopenharmony_ci * 8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 11e5c31af7Sopenharmony_ci * 12e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 18e5c31af7Sopenharmony_ci * limitations under the License. 19e5c31af7Sopenharmony_ci * 20e5c31af7Sopenharmony_ci */ /*! 21e5c31af7Sopenharmony_ci * \file 22e5c31af7Sopenharmony_ci * \brief Compiler test case. 23e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include "glcShaderLibrary.hpp" 26e5c31af7Sopenharmony_ci#include "glcShaderLibraryCase.hpp" 27e5c31af7Sopenharmony_ci#include "gluShaderUtil.hpp" 28e5c31af7Sopenharmony_ci#include "tcuResource.hpp" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include "deInt32.h" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include <fstream> 33e5c31af7Sopenharmony_ci#include <sstream> 34e5c31af7Sopenharmony_ci#include <string> 35e5c31af7Sopenharmony_ci#include <vector> 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci#include <stdarg.h> 38e5c31af7Sopenharmony_ci#include <stdlib.h> 39e5c31af7Sopenharmony_ci#include <string.h> 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ciusing std::string; 42e5c31af7Sopenharmony_ciusing std::vector; 43e5c31af7Sopenharmony_ciusing std::ostringstream; 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ciusing namespace glu; 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ci#if 0 48e5c31af7Sopenharmony_ci#define PARSE_DBG(X) printf X 49e5c31af7Sopenharmony_ci#else 50e5c31af7Sopenharmony_ci#define PARSE_DBG(X) DE_NULL_STATEMENT 51e5c31af7Sopenharmony_ci#endif 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_cinamespace deqp 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_cinamespace sl 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_cistatic const glu::GLSLVersion DEFAULT_GLSL_VERSION = glu::GLSL_VERSION_100_ES; 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ciDE_INLINE deBool isWhitespace(char c) 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_ci return (c == ' ') || (c == '\t') || (c == '\r') || (c == '\n'); 63e5c31af7Sopenharmony_ci} 64e5c31af7Sopenharmony_ci 65e5c31af7Sopenharmony_ciDE_INLINE deBool isEOL(char c) 66e5c31af7Sopenharmony_ci{ 67e5c31af7Sopenharmony_ci return (c == '\r') || (c == '\n'); 68e5c31af7Sopenharmony_ci} 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ciDE_INLINE deBool isNumeric(char c) 71e5c31af7Sopenharmony_ci{ 72e5c31af7Sopenharmony_ci return deInRange32(c, '0', '9'); 73e5c31af7Sopenharmony_ci} 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ciDE_INLINE deBool isAlpha(char c) 76e5c31af7Sopenharmony_ci{ 77e5c31af7Sopenharmony_ci return deInRange32(c, 'a', 'z') || deInRange32(c, 'A', 'Z'); 78e5c31af7Sopenharmony_ci} 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_ciDE_INLINE deBool isCaseNameChar(char c) 81e5c31af7Sopenharmony_ci{ 82e5c31af7Sopenharmony_ci return deInRange32(c, 'a', 'z') || deInRange32(c, 'A', 'Z') || deInRange32(c, '0', '9') || (c == '_') || 83e5c31af7Sopenharmony_ci (c == '-') || (c == '.'); 84e5c31af7Sopenharmony_ci} 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_ci// \todo [2011-02-11 pyry] Should not depend on Context or TestContext! 87e5c31af7Sopenharmony_ciclass ShaderParser 88e5c31af7Sopenharmony_ci{ 89e5c31af7Sopenharmony_cipublic: 90e5c31af7Sopenharmony_ci ShaderParser(tcu::TestContext& testCtx, RenderContext& renderCtx); 91e5c31af7Sopenharmony_ci ~ShaderParser(void); 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci vector<tcu::TestNode*> parse(const char* input); 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ciprivate: 96e5c31af7Sopenharmony_ci enum Token 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci TOKEN_INVALID = 0, 99e5c31af7Sopenharmony_ci TOKEN_EOF, 100e5c31af7Sopenharmony_ci TOKEN_STRING, 101e5c31af7Sopenharmony_ci TOKEN_SHADER_SOURCE, 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ci TOKEN_INT_LITERAL, 104e5c31af7Sopenharmony_ci TOKEN_FLOAT_LITERAL, 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ci // identifiers 107e5c31af7Sopenharmony_ci TOKEN_IDENTIFIER, 108e5c31af7Sopenharmony_ci TOKEN_TRUE, 109e5c31af7Sopenharmony_ci TOKEN_FALSE, 110e5c31af7Sopenharmony_ci TOKEN_DESC, 111e5c31af7Sopenharmony_ci TOKEN_EXPECT, 112e5c31af7Sopenharmony_ci TOKEN_GROUP, 113e5c31af7Sopenharmony_ci TOKEN_CASE, 114e5c31af7Sopenharmony_ci TOKEN_END, 115e5c31af7Sopenharmony_ci TOKEN_VALUES, 116e5c31af7Sopenharmony_ci TOKEN_BOTH, 117e5c31af7Sopenharmony_ci TOKEN_VERTEX, 118e5c31af7Sopenharmony_ci TOKEN_FRAGMENT, 119e5c31af7Sopenharmony_ci TOKEN_UNIFORM, 120e5c31af7Sopenharmony_ci TOKEN_INPUT, 121e5c31af7Sopenharmony_ci TOKEN_OUTPUT, 122e5c31af7Sopenharmony_ci TOKEN_FLOAT, 123e5c31af7Sopenharmony_ci TOKEN_FLOAT_VEC2, 124e5c31af7Sopenharmony_ci TOKEN_FLOAT_VEC3, 125e5c31af7Sopenharmony_ci TOKEN_FLOAT_VEC4, 126e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT2, 127e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT2X3, 128e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT2X4, 129e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT3X2, 130e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT3, 131e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT3X4, 132e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT4X2, 133e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT4X3, 134e5c31af7Sopenharmony_ci TOKEN_FLOAT_MAT4, 135e5c31af7Sopenharmony_ci TOKEN_INT, 136e5c31af7Sopenharmony_ci TOKEN_INT_VEC2, 137e5c31af7Sopenharmony_ci TOKEN_INT_VEC3, 138e5c31af7Sopenharmony_ci TOKEN_INT_VEC4, 139e5c31af7Sopenharmony_ci TOKEN_UINT, 140e5c31af7Sopenharmony_ci TOKEN_UINT_VEC2, 141e5c31af7Sopenharmony_ci TOKEN_UINT_VEC3, 142e5c31af7Sopenharmony_ci TOKEN_UINT_VEC4, 143e5c31af7Sopenharmony_ci TOKEN_BOOL, 144e5c31af7Sopenharmony_ci TOKEN_BOOL_VEC2, 145e5c31af7Sopenharmony_ci TOKEN_BOOL_VEC3, 146e5c31af7Sopenharmony_ci TOKEN_BOOL_VEC4, 147e5c31af7Sopenharmony_ci TOKEN_VERSION, 148e5c31af7Sopenharmony_ci 149e5c31af7Sopenharmony_ci // symbols 150e5c31af7Sopenharmony_ci TOKEN_ASSIGN, 151e5c31af7Sopenharmony_ci TOKEN_PLUS, 152e5c31af7Sopenharmony_ci TOKEN_MINUS, 153e5c31af7Sopenharmony_ci TOKEN_COMMA, 154e5c31af7Sopenharmony_ci TOKEN_VERTICAL_BAR, 155e5c31af7Sopenharmony_ci TOKEN_SEMI_COLON, 156e5c31af7Sopenharmony_ci TOKEN_LEFT_PAREN, 157e5c31af7Sopenharmony_ci TOKEN_RIGHT_PAREN, 158e5c31af7Sopenharmony_ci TOKEN_LEFT_BRACKET, 159e5c31af7Sopenharmony_ci TOKEN_RIGHT_BRACKET, 160e5c31af7Sopenharmony_ci TOKEN_LEFT_BRACE, 161e5c31af7Sopenharmony_ci TOKEN_RIGHT_BRACE, 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci TOKEN_LAST 164e5c31af7Sopenharmony_ci }; 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ci void parseError(const std::string& errorStr); 167e5c31af7Sopenharmony_ci float parseFloatLiteral(const char* str); 168e5c31af7Sopenharmony_ci long long int parseIntLiteral(const char* str); 169e5c31af7Sopenharmony_ci string parseStringLiteral(const char* str); 170e5c31af7Sopenharmony_ci string parseShaderSource(const char* str); 171e5c31af7Sopenharmony_ci void advanceToken(void); 172e5c31af7Sopenharmony_ci void advanceToken(Token assumed); 173e5c31af7Sopenharmony_ci void assumeToken(Token token); 174e5c31af7Sopenharmony_ci DataType mapDataTypeToken(Token token); 175e5c31af7Sopenharmony_ci const char* getTokenName(Token token); 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci void parseValueElement(DataType dataType, ShaderCase::Value& result); 178e5c31af7Sopenharmony_ci void parseValue(ShaderCase::ValueBlock& valueBlock); 179e5c31af7Sopenharmony_ci void parseValueBlock(ShaderCase::ValueBlock& valueBlock); 180e5c31af7Sopenharmony_ci void parseShaderCase(vector<tcu::TestNode*>& shaderNodeList); 181e5c31af7Sopenharmony_ci void parseShaderGroup(vector<tcu::TestNode*>& shaderNodeList); 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ci // Member variables. 184e5c31af7Sopenharmony_ci tcu::TestContext& m_testCtx; 185e5c31af7Sopenharmony_ci RenderContext& m_renderCtx; 186e5c31af7Sopenharmony_ci std::string m_input; 187e5c31af7Sopenharmony_ci const char* m_curPtr; 188e5c31af7Sopenharmony_ci Token m_curToken; 189e5c31af7Sopenharmony_ci std::string m_curTokenStr; 190e5c31af7Sopenharmony_ci}; 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ciShaderParser::ShaderParser(tcu::TestContext& testCtx, RenderContext& renderCtx) 193e5c31af7Sopenharmony_ci : m_testCtx(testCtx), m_renderCtx(renderCtx), m_curPtr(DE_NULL), m_curToken(TOKEN_LAST) 194e5c31af7Sopenharmony_ci{ 195e5c31af7Sopenharmony_ci} 196e5c31af7Sopenharmony_ci 197e5c31af7Sopenharmony_ciShaderParser::~ShaderParser(void) 198e5c31af7Sopenharmony_ci{ 199e5c31af7Sopenharmony_ci // nada 200e5c31af7Sopenharmony_ci} 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_civoid ShaderParser::parseError(const std::string& errorStr) 203e5c31af7Sopenharmony_ci{ 204e5c31af7Sopenharmony_ci string atStr = string(m_curPtr, 80); 205e5c31af7Sopenharmony_ci throw tcu::InternalError((string("Parser error: ") + errorStr + " near '" + atStr + " ...'").c_str(), "", __FILE__, 206e5c31af7Sopenharmony_ci __LINE__); 207e5c31af7Sopenharmony_ci} 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_cifloat ShaderParser::parseFloatLiteral(const char* str) 210e5c31af7Sopenharmony_ci{ 211e5c31af7Sopenharmony_ci return (float)atof(str); 212e5c31af7Sopenharmony_ci} 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_cilong long int ShaderParser::parseIntLiteral(const char* str) 215e5c31af7Sopenharmony_ci{ 216e5c31af7Sopenharmony_ci return strtoll(str, NULL, 0); 217e5c31af7Sopenharmony_ci} 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_cistring ShaderParser::parseStringLiteral(const char* str) 220e5c31af7Sopenharmony_ci{ 221e5c31af7Sopenharmony_ci const char* p = str; 222e5c31af7Sopenharmony_ci char endChar = *p++; 223e5c31af7Sopenharmony_ci ostringstream o; 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ci while (*p != endChar && *p) 226e5c31af7Sopenharmony_ci { 227e5c31af7Sopenharmony_ci if (*p == '\\') 228e5c31af7Sopenharmony_ci { 229e5c31af7Sopenharmony_ci switch (p[1]) 230e5c31af7Sopenharmony_ci { 231e5c31af7Sopenharmony_ci case 0: 232e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 233e5c31af7Sopenharmony_ci break; 234e5c31af7Sopenharmony_ci case 'n': 235e5c31af7Sopenharmony_ci o << '\n'; 236e5c31af7Sopenharmony_ci break; 237e5c31af7Sopenharmony_ci case 't': 238e5c31af7Sopenharmony_ci o << '\t'; 239e5c31af7Sopenharmony_ci break; 240e5c31af7Sopenharmony_ci default: 241e5c31af7Sopenharmony_ci o << p[1]; 242e5c31af7Sopenharmony_ci break; 243e5c31af7Sopenharmony_ci } 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ci p += 2; 246e5c31af7Sopenharmony_ci } 247e5c31af7Sopenharmony_ci else 248e5c31af7Sopenharmony_ci o << *p++; 249e5c31af7Sopenharmony_ci } 250e5c31af7Sopenharmony_ci 251e5c31af7Sopenharmony_ci return o.str(); 252e5c31af7Sopenharmony_ci} 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_cistatic string removeExtraIndentation(const string& source) 255e5c31af7Sopenharmony_ci{ 256e5c31af7Sopenharmony_ci // Detect indentation from first line. 257e5c31af7Sopenharmony_ci int numIndentChars = 0; 258e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < (int)source.length() && isWhitespace(source[ndx]); ndx++) 259e5c31af7Sopenharmony_ci numIndentChars += source[ndx] == '\t' ? 4 : 1; 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci // Process all lines and remove preceding indentation. 262e5c31af7Sopenharmony_ci ostringstream processed; 263e5c31af7Sopenharmony_ci { 264e5c31af7Sopenharmony_ci bool atLineStart = true; 265e5c31af7Sopenharmony_ci int indentCharsOmitted = 0; 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ci for (int pos = 0; pos < (int)source.length(); pos++) 268e5c31af7Sopenharmony_ci { 269e5c31af7Sopenharmony_ci char c = source[pos]; 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci if (atLineStart && indentCharsOmitted < numIndentChars && (c == ' ' || c == '\t')) 272e5c31af7Sopenharmony_ci { 273e5c31af7Sopenharmony_ci indentCharsOmitted += c == '\t' ? 4 : 1; 274e5c31af7Sopenharmony_ci } 275e5c31af7Sopenharmony_ci else if (isEOL(c)) 276e5c31af7Sopenharmony_ci { 277e5c31af7Sopenharmony_ci if (source[pos] == '\r' && source[pos + 1] == '\n') 278e5c31af7Sopenharmony_ci { 279e5c31af7Sopenharmony_ci pos += 1; 280e5c31af7Sopenharmony_ci processed << '\n'; 281e5c31af7Sopenharmony_ci } 282e5c31af7Sopenharmony_ci else 283e5c31af7Sopenharmony_ci processed << c; 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ci atLineStart = true; 286e5c31af7Sopenharmony_ci indentCharsOmitted = 0; 287e5c31af7Sopenharmony_ci } 288e5c31af7Sopenharmony_ci else 289e5c31af7Sopenharmony_ci { 290e5c31af7Sopenharmony_ci processed << c; 291e5c31af7Sopenharmony_ci atLineStart = false; 292e5c31af7Sopenharmony_ci } 293e5c31af7Sopenharmony_ci } 294e5c31af7Sopenharmony_ci } 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ci return processed.str(); 297e5c31af7Sopenharmony_ci} 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_cistring ShaderParser::parseShaderSource(const char* str) 300e5c31af7Sopenharmony_ci{ 301e5c31af7Sopenharmony_ci const char* p = str + 2; 302e5c31af7Sopenharmony_ci ostringstream o; 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci // Eat first empty line from beginning. 305e5c31af7Sopenharmony_ci while (*p == ' ') 306e5c31af7Sopenharmony_ci p++; 307e5c31af7Sopenharmony_ci while (isEOL(*p)) 308e5c31af7Sopenharmony_ci p++; 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ci while ((p[0] != '"') || (p[1] != '"')) 311e5c31af7Sopenharmony_ci { 312e5c31af7Sopenharmony_ci if (*p == '\\') 313e5c31af7Sopenharmony_ci { 314e5c31af7Sopenharmony_ci switch (p[1]) 315e5c31af7Sopenharmony_ci { 316e5c31af7Sopenharmony_ci case 0: 317e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 318e5c31af7Sopenharmony_ci break; 319e5c31af7Sopenharmony_ci case 'n': 320e5c31af7Sopenharmony_ci o << '\n'; 321e5c31af7Sopenharmony_ci break; 322e5c31af7Sopenharmony_ci case 't': 323e5c31af7Sopenharmony_ci o << '\t'; 324e5c31af7Sopenharmony_ci break; 325e5c31af7Sopenharmony_ci default: 326e5c31af7Sopenharmony_ci o << p[1]; 327e5c31af7Sopenharmony_ci break; 328e5c31af7Sopenharmony_ci } 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci p += 2; 331e5c31af7Sopenharmony_ci } 332e5c31af7Sopenharmony_ci else 333e5c31af7Sopenharmony_ci o << *p++; 334e5c31af7Sopenharmony_ci } 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci return removeExtraIndentation(o.str()); 337e5c31af7Sopenharmony_ci} 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_civoid ShaderParser::advanceToken(void) 340e5c31af7Sopenharmony_ci{ 341e5c31af7Sopenharmony_ci // Skip old token. 342e5c31af7Sopenharmony_ci m_curPtr += m_curTokenStr.length(); 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci // Reset token (for safety). 345e5c31af7Sopenharmony_ci m_curToken = TOKEN_INVALID; 346e5c31af7Sopenharmony_ci m_curTokenStr = ""; 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci // Eat whitespace & comments while they last. 349e5c31af7Sopenharmony_ci for (;;) 350e5c31af7Sopenharmony_ci { 351e5c31af7Sopenharmony_ci while (isWhitespace(*m_curPtr)) 352e5c31af7Sopenharmony_ci m_curPtr++; 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_ci // Check for EOL comment. 355e5c31af7Sopenharmony_ci if (*m_curPtr == '#') 356e5c31af7Sopenharmony_ci { 357e5c31af7Sopenharmony_ci while (*m_curPtr && !isEOL(*m_curPtr)) 358e5c31af7Sopenharmony_ci m_curPtr++; 359e5c31af7Sopenharmony_ci } 360e5c31af7Sopenharmony_ci else 361e5c31af7Sopenharmony_ci break; 362e5c31af7Sopenharmony_ci } 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ci if (!*m_curPtr) 365e5c31af7Sopenharmony_ci { 366e5c31af7Sopenharmony_ci m_curToken = TOKEN_EOF; 367e5c31af7Sopenharmony_ci m_curTokenStr = "<EOF>"; 368e5c31af7Sopenharmony_ci } 369e5c31af7Sopenharmony_ci else if (isAlpha(*m_curPtr)) 370e5c31af7Sopenharmony_ci { 371e5c31af7Sopenharmony_ci struct Named 372e5c31af7Sopenharmony_ci { 373e5c31af7Sopenharmony_ci const char* str; 374e5c31af7Sopenharmony_ci Token token; 375e5c31af7Sopenharmony_ci }; 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci static const Named s_named[] = { { "true", TOKEN_TRUE }, 378e5c31af7Sopenharmony_ci { "false", TOKEN_FALSE }, 379e5c31af7Sopenharmony_ci { "desc", TOKEN_DESC }, 380e5c31af7Sopenharmony_ci { "expect", TOKEN_EXPECT }, 381e5c31af7Sopenharmony_ci { "group", TOKEN_GROUP }, 382e5c31af7Sopenharmony_ci { "case", TOKEN_CASE }, 383e5c31af7Sopenharmony_ci { "end", TOKEN_END }, 384e5c31af7Sopenharmony_ci { "values", TOKEN_VALUES }, 385e5c31af7Sopenharmony_ci { "both", TOKEN_BOTH }, 386e5c31af7Sopenharmony_ci { "vertex", TOKEN_VERTEX }, 387e5c31af7Sopenharmony_ci { "fragment", TOKEN_FRAGMENT }, 388e5c31af7Sopenharmony_ci { "uniform", TOKEN_UNIFORM }, 389e5c31af7Sopenharmony_ci { "input", TOKEN_INPUT }, 390e5c31af7Sopenharmony_ci { "output", TOKEN_OUTPUT }, 391e5c31af7Sopenharmony_ci { "float", TOKEN_FLOAT }, 392e5c31af7Sopenharmony_ci { "vec2", TOKEN_FLOAT_VEC2 }, 393e5c31af7Sopenharmony_ci { "vec3", TOKEN_FLOAT_VEC3 }, 394e5c31af7Sopenharmony_ci { "vec4", TOKEN_FLOAT_VEC4 }, 395e5c31af7Sopenharmony_ci { "mat2", TOKEN_FLOAT_MAT2 }, 396e5c31af7Sopenharmony_ci { "mat2x3", TOKEN_FLOAT_MAT2X3 }, 397e5c31af7Sopenharmony_ci { "mat2x4", TOKEN_FLOAT_MAT2X4 }, 398e5c31af7Sopenharmony_ci { "mat3x2", TOKEN_FLOAT_MAT3X2 }, 399e5c31af7Sopenharmony_ci { "mat3", TOKEN_FLOAT_MAT3 }, 400e5c31af7Sopenharmony_ci { "mat3x4", TOKEN_FLOAT_MAT3X4 }, 401e5c31af7Sopenharmony_ci { "mat4x2", TOKEN_FLOAT_MAT4X2 }, 402e5c31af7Sopenharmony_ci { "mat4x3", TOKEN_FLOAT_MAT4X3 }, 403e5c31af7Sopenharmony_ci { "mat4", TOKEN_FLOAT_MAT4 }, 404e5c31af7Sopenharmony_ci { "int", TOKEN_INT }, 405e5c31af7Sopenharmony_ci { "ivec2", TOKEN_INT_VEC2 }, 406e5c31af7Sopenharmony_ci { "ivec3", TOKEN_INT_VEC3 }, 407e5c31af7Sopenharmony_ci { "ivec4", TOKEN_INT_VEC4 }, 408e5c31af7Sopenharmony_ci { "uint", TOKEN_UINT }, 409e5c31af7Sopenharmony_ci { "uvec2", TOKEN_UINT_VEC2 }, 410e5c31af7Sopenharmony_ci { "uvec3", TOKEN_UINT_VEC3 }, 411e5c31af7Sopenharmony_ci { "uvec4", TOKEN_UINT_VEC4 }, 412e5c31af7Sopenharmony_ci { "bool", TOKEN_BOOL }, 413e5c31af7Sopenharmony_ci { "bvec2", TOKEN_BOOL_VEC2 }, 414e5c31af7Sopenharmony_ci { "bvec3", TOKEN_BOOL_VEC3 }, 415e5c31af7Sopenharmony_ci { "bvec4", TOKEN_BOOL_VEC4 }, 416e5c31af7Sopenharmony_ci { "version", TOKEN_VERSION } }; 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci const char* end = m_curPtr + 1; 419e5c31af7Sopenharmony_ci while (isCaseNameChar(*end)) 420e5c31af7Sopenharmony_ci end++; 421e5c31af7Sopenharmony_ci m_curTokenStr = string(m_curPtr, end - m_curPtr); 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci m_curToken = TOKEN_IDENTIFIER; 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_named); ndx++) 426e5c31af7Sopenharmony_ci { 427e5c31af7Sopenharmony_ci if (m_curTokenStr == s_named[ndx].str) 428e5c31af7Sopenharmony_ci { 429e5c31af7Sopenharmony_ci m_curToken = s_named[ndx].token; 430e5c31af7Sopenharmony_ci break; 431e5c31af7Sopenharmony_ci } 432e5c31af7Sopenharmony_ci } 433e5c31af7Sopenharmony_ci } 434e5c31af7Sopenharmony_ci else if (isNumeric(*m_curPtr)) 435e5c31af7Sopenharmony_ci { 436e5c31af7Sopenharmony_ci /* \todo [2010-03-31 petri] Hex? */ 437e5c31af7Sopenharmony_ci const char* p = m_curPtr; 438e5c31af7Sopenharmony_ci while (isNumeric(*p)) 439e5c31af7Sopenharmony_ci p++; 440e5c31af7Sopenharmony_ci if (*p == '.') 441e5c31af7Sopenharmony_ci { 442e5c31af7Sopenharmony_ci p++; 443e5c31af7Sopenharmony_ci while (isNumeric(*p)) 444e5c31af7Sopenharmony_ci p++; 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_ci if (*p == 'e' || *p == 'E') 447e5c31af7Sopenharmony_ci { 448e5c31af7Sopenharmony_ci p++; 449e5c31af7Sopenharmony_ci if (*p == '+' || *p == '-') 450e5c31af7Sopenharmony_ci p++; 451e5c31af7Sopenharmony_ci DE_ASSERT(isNumeric(*p)); 452e5c31af7Sopenharmony_ci while (isNumeric(*p)) 453e5c31af7Sopenharmony_ci p++; 454e5c31af7Sopenharmony_ci } 455e5c31af7Sopenharmony_ci 456e5c31af7Sopenharmony_ci m_curToken = TOKEN_FLOAT_LITERAL; 457e5c31af7Sopenharmony_ci m_curTokenStr = string(m_curPtr, p - m_curPtr); 458e5c31af7Sopenharmony_ci } 459e5c31af7Sopenharmony_ci else 460e5c31af7Sopenharmony_ci { 461e5c31af7Sopenharmony_ci m_curToken = TOKEN_INT_LITERAL; 462e5c31af7Sopenharmony_ci m_curTokenStr = string(m_curPtr, p - m_curPtr); 463e5c31af7Sopenharmony_ci } 464e5c31af7Sopenharmony_ci } 465e5c31af7Sopenharmony_ci else if (*m_curPtr == '"' && m_curPtr[1] == '"') 466e5c31af7Sopenharmony_ci { 467e5c31af7Sopenharmony_ci const char* p = m_curPtr + 2; 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_ci while ((p[0] != '"') || (p[1] != '"')) 470e5c31af7Sopenharmony_ci { 471e5c31af7Sopenharmony_ci DE_ASSERT(*p); 472e5c31af7Sopenharmony_ci if (*p == '\\') 473e5c31af7Sopenharmony_ci { 474e5c31af7Sopenharmony_ci DE_ASSERT(p[1] != 0); 475e5c31af7Sopenharmony_ci p += 2; 476e5c31af7Sopenharmony_ci } 477e5c31af7Sopenharmony_ci else 478e5c31af7Sopenharmony_ci p++; 479e5c31af7Sopenharmony_ci } 480e5c31af7Sopenharmony_ci p += 2; 481e5c31af7Sopenharmony_ci 482e5c31af7Sopenharmony_ci m_curToken = TOKEN_SHADER_SOURCE; 483e5c31af7Sopenharmony_ci m_curTokenStr = string(m_curPtr, (int)(p - m_curPtr)); 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci else if (*m_curPtr == '"' || *m_curPtr == '\'') 486e5c31af7Sopenharmony_ci { 487e5c31af7Sopenharmony_ci char endChar = *m_curPtr; 488e5c31af7Sopenharmony_ci const char* p = m_curPtr + 1; 489e5c31af7Sopenharmony_ci 490e5c31af7Sopenharmony_ci while (*p != endChar) 491e5c31af7Sopenharmony_ci { 492e5c31af7Sopenharmony_ci DE_ASSERT(*p); 493e5c31af7Sopenharmony_ci if (*p == '\\') 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci DE_ASSERT(p[1] != 0); 496e5c31af7Sopenharmony_ci p += 2; 497e5c31af7Sopenharmony_ci } 498e5c31af7Sopenharmony_ci else 499e5c31af7Sopenharmony_ci p++; 500e5c31af7Sopenharmony_ci } 501e5c31af7Sopenharmony_ci p++; 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci m_curToken = TOKEN_STRING; 504e5c31af7Sopenharmony_ci m_curTokenStr = string(m_curPtr, (int)(p - m_curPtr)); 505e5c31af7Sopenharmony_ci } 506e5c31af7Sopenharmony_ci else 507e5c31af7Sopenharmony_ci { 508e5c31af7Sopenharmony_ci struct SimpleToken 509e5c31af7Sopenharmony_ci { 510e5c31af7Sopenharmony_ci const char* str; 511e5c31af7Sopenharmony_ci Token token; 512e5c31af7Sopenharmony_ci }; 513e5c31af7Sopenharmony_ci 514e5c31af7Sopenharmony_ci static const SimpleToken s_simple[] = { { "=", TOKEN_ASSIGN }, { "+", TOKEN_PLUS }, 515e5c31af7Sopenharmony_ci { "-", TOKEN_MINUS }, { ",", TOKEN_COMMA }, 516e5c31af7Sopenharmony_ci { "|", TOKEN_VERTICAL_BAR }, { ";", TOKEN_SEMI_COLON }, 517e5c31af7Sopenharmony_ci { "(", TOKEN_LEFT_PAREN }, { ")", TOKEN_RIGHT_PAREN }, 518e5c31af7Sopenharmony_ci { "[", TOKEN_LEFT_BRACKET }, { "]", TOKEN_RIGHT_BRACKET }, 519e5c31af7Sopenharmony_ci { "{", TOKEN_LEFT_BRACE }, { "}", TOKEN_RIGHT_BRACE } }; 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_simple); ndx++) 522e5c31af7Sopenharmony_ci { 523e5c31af7Sopenharmony_ci if (strncmp(s_simple[ndx].str, m_curPtr, strlen(s_simple[ndx].str)) == 0) 524e5c31af7Sopenharmony_ci { 525e5c31af7Sopenharmony_ci m_curToken = s_simple[ndx].token; 526e5c31af7Sopenharmony_ci m_curTokenStr = s_simple[ndx].str; 527e5c31af7Sopenharmony_ci return; 528e5c31af7Sopenharmony_ci } 529e5c31af7Sopenharmony_ci } 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci // Otherwise invalid token. 532e5c31af7Sopenharmony_ci m_curToken = TOKEN_INVALID; 533e5c31af7Sopenharmony_ci m_curTokenStr = *m_curPtr; 534e5c31af7Sopenharmony_ci } 535e5c31af7Sopenharmony_ci} 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_civoid ShaderParser::advanceToken(Token assumed) 538e5c31af7Sopenharmony_ci{ 539e5c31af7Sopenharmony_ci assumeToken(assumed); 540e5c31af7Sopenharmony_ci advanceToken(); 541e5c31af7Sopenharmony_ci} 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_civoid ShaderParser::assumeToken(Token token) 544e5c31af7Sopenharmony_ci{ 545e5c31af7Sopenharmony_ci if (m_curToken != token) 546e5c31af7Sopenharmony_ci parseError( 547e5c31af7Sopenharmony_ci (string("unexpected token '") + m_curTokenStr + "', expecting '" + getTokenName(token) + "'").c_str()); 548e5c31af7Sopenharmony_ci DE_TEST_ASSERT(m_curToken == token); 549e5c31af7Sopenharmony_ci} 550e5c31af7Sopenharmony_ci 551e5c31af7Sopenharmony_ciDataType ShaderParser::mapDataTypeToken(Token token) 552e5c31af7Sopenharmony_ci{ 553e5c31af7Sopenharmony_ci switch (token) 554e5c31af7Sopenharmony_ci { 555e5c31af7Sopenharmony_ci case TOKEN_FLOAT: 556e5c31af7Sopenharmony_ci return TYPE_FLOAT; 557e5c31af7Sopenharmony_ci case TOKEN_FLOAT_VEC2: 558e5c31af7Sopenharmony_ci return TYPE_FLOAT_VEC2; 559e5c31af7Sopenharmony_ci case TOKEN_FLOAT_VEC3: 560e5c31af7Sopenharmony_ci return TYPE_FLOAT_VEC3; 561e5c31af7Sopenharmony_ci case TOKEN_FLOAT_VEC4: 562e5c31af7Sopenharmony_ci return TYPE_FLOAT_VEC4; 563e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT2: 564e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT2; 565e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT2X3: 566e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT2X3; 567e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT2X4: 568e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT2X4; 569e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT3X2: 570e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT3X2; 571e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT3: 572e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT3; 573e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT3X4: 574e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT3X4; 575e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT4X2: 576e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT4X2; 577e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT4X3: 578e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT4X3; 579e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT4: 580e5c31af7Sopenharmony_ci return TYPE_FLOAT_MAT4; 581e5c31af7Sopenharmony_ci case TOKEN_INT: 582e5c31af7Sopenharmony_ci return TYPE_INT; 583e5c31af7Sopenharmony_ci case TOKEN_INT_VEC2: 584e5c31af7Sopenharmony_ci return TYPE_INT_VEC2; 585e5c31af7Sopenharmony_ci case TOKEN_INT_VEC3: 586e5c31af7Sopenharmony_ci return TYPE_INT_VEC3; 587e5c31af7Sopenharmony_ci case TOKEN_INT_VEC4: 588e5c31af7Sopenharmony_ci return TYPE_INT_VEC4; 589e5c31af7Sopenharmony_ci case TOKEN_UINT: 590e5c31af7Sopenharmony_ci return TYPE_UINT; 591e5c31af7Sopenharmony_ci case TOKEN_UINT_VEC2: 592e5c31af7Sopenharmony_ci return TYPE_UINT_VEC2; 593e5c31af7Sopenharmony_ci case TOKEN_UINT_VEC3: 594e5c31af7Sopenharmony_ci return TYPE_UINT_VEC3; 595e5c31af7Sopenharmony_ci case TOKEN_UINT_VEC4: 596e5c31af7Sopenharmony_ci return TYPE_UINT_VEC4; 597e5c31af7Sopenharmony_ci case TOKEN_BOOL: 598e5c31af7Sopenharmony_ci return TYPE_BOOL; 599e5c31af7Sopenharmony_ci case TOKEN_BOOL_VEC2: 600e5c31af7Sopenharmony_ci return TYPE_BOOL_VEC2; 601e5c31af7Sopenharmony_ci case TOKEN_BOOL_VEC3: 602e5c31af7Sopenharmony_ci return TYPE_BOOL_VEC3; 603e5c31af7Sopenharmony_ci case TOKEN_BOOL_VEC4: 604e5c31af7Sopenharmony_ci return TYPE_BOOL_VEC4; 605e5c31af7Sopenharmony_ci default: 606e5c31af7Sopenharmony_ci return TYPE_INVALID; 607e5c31af7Sopenharmony_ci } 608e5c31af7Sopenharmony_ci} 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ciconst char* ShaderParser::getTokenName(Token token) 611e5c31af7Sopenharmony_ci{ 612e5c31af7Sopenharmony_ci switch (token) 613e5c31af7Sopenharmony_ci { 614e5c31af7Sopenharmony_ci case TOKEN_INVALID: 615e5c31af7Sopenharmony_ci return "<invalid>"; 616e5c31af7Sopenharmony_ci case TOKEN_EOF: 617e5c31af7Sopenharmony_ci return "<eof>"; 618e5c31af7Sopenharmony_ci case TOKEN_STRING: 619e5c31af7Sopenharmony_ci return "<string>"; 620e5c31af7Sopenharmony_ci case TOKEN_SHADER_SOURCE: 621e5c31af7Sopenharmony_ci return "source"; 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci case TOKEN_INT_LITERAL: 624e5c31af7Sopenharmony_ci return "<int>"; 625e5c31af7Sopenharmony_ci case TOKEN_FLOAT_LITERAL: 626e5c31af7Sopenharmony_ci return "<float>"; 627e5c31af7Sopenharmony_ci 628e5c31af7Sopenharmony_ci // identifiers 629e5c31af7Sopenharmony_ci case TOKEN_IDENTIFIER: 630e5c31af7Sopenharmony_ci return "<identifier>"; 631e5c31af7Sopenharmony_ci case TOKEN_TRUE: 632e5c31af7Sopenharmony_ci return "true"; 633e5c31af7Sopenharmony_ci case TOKEN_FALSE: 634e5c31af7Sopenharmony_ci return "false"; 635e5c31af7Sopenharmony_ci case TOKEN_DESC: 636e5c31af7Sopenharmony_ci return "desc"; 637e5c31af7Sopenharmony_ci case TOKEN_EXPECT: 638e5c31af7Sopenharmony_ci return "expect"; 639e5c31af7Sopenharmony_ci case TOKEN_GROUP: 640e5c31af7Sopenharmony_ci return "group"; 641e5c31af7Sopenharmony_ci case TOKEN_CASE: 642e5c31af7Sopenharmony_ci return "case"; 643e5c31af7Sopenharmony_ci case TOKEN_END: 644e5c31af7Sopenharmony_ci return "end"; 645e5c31af7Sopenharmony_ci case TOKEN_VALUES: 646e5c31af7Sopenharmony_ci return "values"; 647e5c31af7Sopenharmony_ci case TOKEN_BOTH: 648e5c31af7Sopenharmony_ci return "both"; 649e5c31af7Sopenharmony_ci case TOKEN_VERTEX: 650e5c31af7Sopenharmony_ci return "vertex"; 651e5c31af7Sopenharmony_ci case TOKEN_FRAGMENT: 652e5c31af7Sopenharmony_ci return "fragment"; 653e5c31af7Sopenharmony_ci case TOKEN_UNIFORM: 654e5c31af7Sopenharmony_ci return "uniform"; 655e5c31af7Sopenharmony_ci case TOKEN_INPUT: 656e5c31af7Sopenharmony_ci return "input"; 657e5c31af7Sopenharmony_ci case TOKEN_OUTPUT: 658e5c31af7Sopenharmony_ci return "output"; 659e5c31af7Sopenharmony_ci case TOKEN_FLOAT: 660e5c31af7Sopenharmony_ci return "float"; 661e5c31af7Sopenharmony_ci case TOKEN_FLOAT_VEC2: 662e5c31af7Sopenharmony_ci return "vec2"; 663e5c31af7Sopenharmony_ci case TOKEN_FLOAT_VEC3: 664e5c31af7Sopenharmony_ci return "vec3"; 665e5c31af7Sopenharmony_ci case TOKEN_FLOAT_VEC4: 666e5c31af7Sopenharmony_ci return "vec4"; 667e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT2: 668e5c31af7Sopenharmony_ci return "mat2"; 669e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT2X3: 670e5c31af7Sopenharmony_ci return "mat2x3"; 671e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT2X4: 672e5c31af7Sopenharmony_ci return "mat2x4"; 673e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT3X2: 674e5c31af7Sopenharmony_ci return "mat3x2"; 675e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT3: 676e5c31af7Sopenharmony_ci return "mat3"; 677e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT3X4: 678e5c31af7Sopenharmony_ci return "mat3x4"; 679e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT4X2: 680e5c31af7Sopenharmony_ci return "mat4x2"; 681e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT4X3: 682e5c31af7Sopenharmony_ci return "mat4x3"; 683e5c31af7Sopenharmony_ci case TOKEN_FLOAT_MAT4: 684e5c31af7Sopenharmony_ci return "mat4"; 685e5c31af7Sopenharmony_ci case TOKEN_INT: 686e5c31af7Sopenharmony_ci return "int"; 687e5c31af7Sopenharmony_ci case TOKEN_INT_VEC2: 688e5c31af7Sopenharmony_ci return "ivec2"; 689e5c31af7Sopenharmony_ci case TOKEN_INT_VEC3: 690e5c31af7Sopenharmony_ci return "ivec3"; 691e5c31af7Sopenharmony_ci case TOKEN_INT_VEC4: 692e5c31af7Sopenharmony_ci return "ivec4"; 693e5c31af7Sopenharmony_ci case TOKEN_UINT: 694e5c31af7Sopenharmony_ci return "uint"; 695e5c31af7Sopenharmony_ci case TOKEN_UINT_VEC2: 696e5c31af7Sopenharmony_ci return "uvec2"; 697e5c31af7Sopenharmony_ci case TOKEN_UINT_VEC3: 698e5c31af7Sopenharmony_ci return "uvec3"; 699e5c31af7Sopenharmony_ci case TOKEN_UINT_VEC4: 700e5c31af7Sopenharmony_ci return "uvec4"; 701e5c31af7Sopenharmony_ci case TOKEN_BOOL: 702e5c31af7Sopenharmony_ci return "bool"; 703e5c31af7Sopenharmony_ci case TOKEN_BOOL_VEC2: 704e5c31af7Sopenharmony_ci return "bvec2"; 705e5c31af7Sopenharmony_ci case TOKEN_BOOL_VEC3: 706e5c31af7Sopenharmony_ci return "bvec3"; 707e5c31af7Sopenharmony_ci case TOKEN_BOOL_VEC4: 708e5c31af7Sopenharmony_ci return "bvec4"; 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci case TOKEN_ASSIGN: 711e5c31af7Sopenharmony_ci return "="; 712e5c31af7Sopenharmony_ci case TOKEN_PLUS: 713e5c31af7Sopenharmony_ci return "+"; 714e5c31af7Sopenharmony_ci case TOKEN_MINUS: 715e5c31af7Sopenharmony_ci return "-"; 716e5c31af7Sopenharmony_ci case TOKEN_COMMA: 717e5c31af7Sopenharmony_ci return ","; 718e5c31af7Sopenharmony_ci case TOKEN_VERTICAL_BAR: 719e5c31af7Sopenharmony_ci return "|"; 720e5c31af7Sopenharmony_ci case TOKEN_SEMI_COLON: 721e5c31af7Sopenharmony_ci return ";"; 722e5c31af7Sopenharmony_ci case TOKEN_LEFT_PAREN: 723e5c31af7Sopenharmony_ci return "("; 724e5c31af7Sopenharmony_ci case TOKEN_RIGHT_PAREN: 725e5c31af7Sopenharmony_ci return ")"; 726e5c31af7Sopenharmony_ci case TOKEN_LEFT_BRACKET: 727e5c31af7Sopenharmony_ci return "["; 728e5c31af7Sopenharmony_ci case TOKEN_RIGHT_BRACKET: 729e5c31af7Sopenharmony_ci return "]"; 730e5c31af7Sopenharmony_ci case TOKEN_LEFT_BRACE: 731e5c31af7Sopenharmony_ci return "{"; 732e5c31af7Sopenharmony_ci case TOKEN_RIGHT_BRACE: 733e5c31af7Sopenharmony_ci return "}"; 734e5c31af7Sopenharmony_ci 735e5c31af7Sopenharmony_ci default: 736e5c31af7Sopenharmony_ci return "<unknown>"; 737e5c31af7Sopenharmony_ci } 738e5c31af7Sopenharmony_ci} 739e5c31af7Sopenharmony_ci 740e5c31af7Sopenharmony_civoid ShaderParser::parseValueElement(DataType expectedDataType, ShaderCase::Value& result) 741e5c31af7Sopenharmony_ci{ 742e5c31af7Sopenharmony_ci DataType scalarType = getDataTypeScalarType(expectedDataType); 743e5c31af7Sopenharmony_ci int scalarSize = getDataTypeScalarSize(expectedDataType); 744e5c31af7Sopenharmony_ci 745e5c31af7Sopenharmony_ci /* \todo [2010-04-19 petri] Support arrays. */ 746e5c31af7Sopenharmony_ci ShaderCase::Value::Element elems[16]; 747e5c31af7Sopenharmony_ci 748e5c31af7Sopenharmony_ci if (scalarSize > 1) 749e5c31af7Sopenharmony_ci { 750e5c31af7Sopenharmony_ci DE_ASSERT(mapDataTypeToken(m_curToken) == expectedDataType); 751e5c31af7Sopenharmony_ci advanceToken(); // data type (float, vec2, etc.) 752e5c31af7Sopenharmony_ci advanceToken(TOKEN_LEFT_PAREN); 753e5c31af7Sopenharmony_ci } 754e5c31af7Sopenharmony_ci 755e5c31af7Sopenharmony_ci for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 756e5c31af7Sopenharmony_ci { 757e5c31af7Sopenharmony_ci if (scalarType == TYPE_FLOAT) 758e5c31af7Sopenharmony_ci { 759e5c31af7Sopenharmony_ci float signMult = 1.0f; 760e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_MINUS) 761e5c31af7Sopenharmony_ci { 762e5c31af7Sopenharmony_ci signMult = -1.0f; 763e5c31af7Sopenharmony_ci advanceToken(); 764e5c31af7Sopenharmony_ci } 765e5c31af7Sopenharmony_ci 766e5c31af7Sopenharmony_ci assumeToken(TOKEN_FLOAT_LITERAL); 767e5c31af7Sopenharmony_ci elems[scalarNdx].float32 = signMult * parseFloatLiteral(m_curTokenStr.c_str()); 768e5c31af7Sopenharmony_ci advanceToken(TOKEN_FLOAT_LITERAL); 769e5c31af7Sopenharmony_ci } 770e5c31af7Sopenharmony_ci else if (scalarType == TYPE_INT || scalarType == TYPE_UINT) 771e5c31af7Sopenharmony_ci { 772e5c31af7Sopenharmony_ci int signMult = 1; 773e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_MINUS) 774e5c31af7Sopenharmony_ci { 775e5c31af7Sopenharmony_ci signMult = -1; 776e5c31af7Sopenharmony_ci advanceToken(); 777e5c31af7Sopenharmony_ci } 778e5c31af7Sopenharmony_ci 779e5c31af7Sopenharmony_ci assumeToken(TOKEN_INT_LITERAL); 780e5c31af7Sopenharmony_ci elems[scalarNdx].int32 = (deInt32)(signMult * parseIntLiteral(m_curTokenStr.c_str())); 781e5c31af7Sopenharmony_ci advanceToken(TOKEN_INT_LITERAL); 782e5c31af7Sopenharmony_ci } 783e5c31af7Sopenharmony_ci else 784e5c31af7Sopenharmony_ci { 785e5c31af7Sopenharmony_ci DE_ASSERT(scalarType == TYPE_BOOL); 786e5c31af7Sopenharmony_ci elems[scalarNdx].bool32 = (m_curToken == TOKEN_TRUE); 787e5c31af7Sopenharmony_ci if (m_curToken != TOKEN_TRUE && m_curToken != TOKEN_FALSE) 788e5c31af7Sopenharmony_ci parseError(string("unexpected token, expecting bool: " + m_curTokenStr)); 789e5c31af7Sopenharmony_ci advanceToken(); // true/false 790e5c31af7Sopenharmony_ci } 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci if (scalarNdx != (scalarSize - 1)) 793e5c31af7Sopenharmony_ci advanceToken(TOKEN_COMMA); 794e5c31af7Sopenharmony_ci } 795e5c31af7Sopenharmony_ci 796e5c31af7Sopenharmony_ci if (scalarSize > 1) 797e5c31af7Sopenharmony_ci advanceToken(TOKEN_RIGHT_PAREN); 798e5c31af7Sopenharmony_ci 799e5c31af7Sopenharmony_ci // Store results. 800e5c31af7Sopenharmony_ci for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 801e5c31af7Sopenharmony_ci result.elements.push_back(elems[scalarNdx]); 802e5c31af7Sopenharmony_ci} 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_civoid ShaderParser::parseValue(ShaderCase::ValueBlock& valueBlock) 805e5c31af7Sopenharmony_ci{ 806e5c31af7Sopenharmony_ci PARSE_DBG((" parseValue()\n")); 807e5c31af7Sopenharmony_ci 808e5c31af7Sopenharmony_ci // Parsed results. 809e5c31af7Sopenharmony_ci ShaderCase::Value result; 810e5c31af7Sopenharmony_ci 811e5c31af7Sopenharmony_ci // Parse storage. 812e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_UNIFORM) 813e5c31af7Sopenharmony_ci result.storageType = ShaderCase::Value::STORAGE_UNIFORM; 814e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_INPUT) 815e5c31af7Sopenharmony_ci result.storageType = ShaderCase::Value::STORAGE_INPUT; 816e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_OUTPUT) 817e5c31af7Sopenharmony_ci result.storageType = ShaderCase::Value::STORAGE_OUTPUT; 818e5c31af7Sopenharmony_ci else 819e5c31af7Sopenharmony_ci parseError(string("unexpected token encountered when parsing value classifier")); 820e5c31af7Sopenharmony_ci advanceToken(); 821e5c31af7Sopenharmony_ci 822e5c31af7Sopenharmony_ci // Parse data type. 823e5c31af7Sopenharmony_ci result.dataType = mapDataTypeToken(m_curToken); 824e5c31af7Sopenharmony_ci if (result.dataType == TYPE_INVALID) 825e5c31af7Sopenharmony_ci parseError(string("unexpected token when parsing value data type: " + m_curTokenStr)); 826e5c31af7Sopenharmony_ci advanceToken(); 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci // Parse value name. 829e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_IDENTIFIER || m_curToken == TOKEN_STRING) 830e5c31af7Sopenharmony_ci { 831e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_IDENTIFIER) 832e5c31af7Sopenharmony_ci result.valueName = m_curTokenStr; 833e5c31af7Sopenharmony_ci else 834e5c31af7Sopenharmony_ci result.valueName = parseStringLiteral(m_curTokenStr.c_str()); 835e5c31af7Sopenharmony_ci } 836e5c31af7Sopenharmony_ci else 837e5c31af7Sopenharmony_ci parseError(string("unexpected token when parsing value name: " + m_curTokenStr)); 838e5c31af7Sopenharmony_ci advanceToken(); 839e5c31af7Sopenharmony_ci 840e5c31af7Sopenharmony_ci // Parse assignment operator. 841e5c31af7Sopenharmony_ci advanceToken(TOKEN_ASSIGN); 842e5c31af7Sopenharmony_ci 843e5c31af7Sopenharmony_ci // Parse actual value. 844e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_LEFT_BRACKET) // value list 845e5c31af7Sopenharmony_ci { 846e5c31af7Sopenharmony_ci advanceToken(TOKEN_LEFT_BRACKET); 847e5c31af7Sopenharmony_ci result.arrayLength = 0; 848e5c31af7Sopenharmony_ci 849e5c31af7Sopenharmony_ci for (;;) 850e5c31af7Sopenharmony_ci { 851e5c31af7Sopenharmony_ci parseValueElement(result.dataType, result); 852e5c31af7Sopenharmony_ci result.arrayLength++; 853e5c31af7Sopenharmony_ci 854e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_RIGHT_BRACKET) 855e5c31af7Sopenharmony_ci break; 856e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_VERTICAL_BAR) 857e5c31af7Sopenharmony_ci { 858e5c31af7Sopenharmony_ci advanceToken(); 859e5c31af7Sopenharmony_ci continue; 860e5c31af7Sopenharmony_ci } 861e5c31af7Sopenharmony_ci else 862e5c31af7Sopenharmony_ci parseError(string("unexpected token in value element array: " + m_curTokenStr)); 863e5c31af7Sopenharmony_ci } 864e5c31af7Sopenharmony_ci 865e5c31af7Sopenharmony_ci advanceToken(TOKEN_RIGHT_BRACKET); 866e5c31af7Sopenharmony_ci } 867e5c31af7Sopenharmony_ci else // arrays, single elements 868e5c31af7Sopenharmony_ci { 869e5c31af7Sopenharmony_ci parseValueElement(result.dataType, result); 870e5c31af7Sopenharmony_ci result.arrayLength = 1; 871e5c31af7Sopenharmony_ci } 872e5c31af7Sopenharmony_ci 873e5c31af7Sopenharmony_ci advanceToken(TOKEN_SEMI_COLON); // end of declaration 874e5c31af7Sopenharmony_ci 875e5c31af7Sopenharmony_ci valueBlock.values.push_back(result); 876e5c31af7Sopenharmony_ci} 877e5c31af7Sopenharmony_ci 878e5c31af7Sopenharmony_civoid ShaderParser::parseValueBlock(ShaderCase::ValueBlock& valueBlock) 879e5c31af7Sopenharmony_ci{ 880e5c31af7Sopenharmony_ci PARSE_DBG((" parseValueBlock()\n")); 881e5c31af7Sopenharmony_ci advanceToken(TOKEN_VALUES); 882e5c31af7Sopenharmony_ci advanceToken(TOKEN_LEFT_BRACE); 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_ci for (;;) 885e5c31af7Sopenharmony_ci { 886e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_UNIFORM || m_curToken == TOKEN_INPUT || m_curToken == TOKEN_OUTPUT) 887e5c31af7Sopenharmony_ci parseValue(valueBlock); 888e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_RIGHT_BRACE) 889e5c31af7Sopenharmony_ci break; 890e5c31af7Sopenharmony_ci else 891e5c31af7Sopenharmony_ci parseError(string("unexpected token when parsing a value block: " + m_curTokenStr)); 892e5c31af7Sopenharmony_ci } 893e5c31af7Sopenharmony_ci 894e5c31af7Sopenharmony_ci advanceToken(TOKEN_RIGHT_BRACE); 895e5c31af7Sopenharmony_ci 896e5c31af7Sopenharmony_ci // Compute combined array length of value block. 897e5c31af7Sopenharmony_ci int arrayLength = 1; 898e5c31af7Sopenharmony_ci for (int valueNdx = 0; valueNdx < (int)valueBlock.values.size(); valueNdx++) 899e5c31af7Sopenharmony_ci { 900e5c31af7Sopenharmony_ci const ShaderCase::Value& val = valueBlock.values[valueNdx]; 901e5c31af7Sopenharmony_ci if (val.arrayLength > 1) 902e5c31af7Sopenharmony_ci { 903e5c31af7Sopenharmony_ci DE_ASSERT(arrayLength == 1 || arrayLength == val.arrayLength); 904e5c31af7Sopenharmony_ci arrayLength = val.arrayLength; 905e5c31af7Sopenharmony_ci } 906e5c31af7Sopenharmony_ci } 907e5c31af7Sopenharmony_ci valueBlock.arrayLength = arrayLength; 908e5c31af7Sopenharmony_ci} 909e5c31af7Sopenharmony_ci 910e5c31af7Sopenharmony_civoid ShaderParser::parseShaderCase(vector<tcu::TestNode*>& shaderNodeList) 911e5c31af7Sopenharmony_ci{ 912e5c31af7Sopenharmony_ci // Parse 'case'. 913e5c31af7Sopenharmony_ci PARSE_DBG((" parseShaderCase()\n")); 914e5c31af7Sopenharmony_ci advanceToken(TOKEN_CASE); 915e5c31af7Sopenharmony_ci 916e5c31af7Sopenharmony_ci // Parse case name. 917e5c31af7Sopenharmony_ci string caseName = m_curTokenStr; 918e5c31af7Sopenharmony_ci advanceToken(); // \note [pyry] All token types are allowed here. 919e5c31af7Sopenharmony_ci 920e5c31af7Sopenharmony_ci // Setup case. 921e5c31af7Sopenharmony_ci vector<ShaderCase::ValueBlock> valueBlockList; 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci GLSLVersion version = DEFAULT_GLSL_VERSION; 924e5c31af7Sopenharmony_ci ShaderCase::ExpectResult expectResult = ShaderCase::EXPECT_PASS; 925e5c31af7Sopenharmony_ci string description; 926e5c31af7Sopenharmony_ci string bothSource; 927e5c31af7Sopenharmony_ci string vertexSource; 928e5c31af7Sopenharmony_ci string fragmentSource; 929e5c31af7Sopenharmony_ci 930e5c31af7Sopenharmony_ci for (;;) 931e5c31af7Sopenharmony_ci { 932e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_END) 933e5c31af7Sopenharmony_ci break; 934e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_DESC) 935e5c31af7Sopenharmony_ci { 936e5c31af7Sopenharmony_ci advanceToken(); 937e5c31af7Sopenharmony_ci assumeToken(TOKEN_STRING); 938e5c31af7Sopenharmony_ci 939e5c31af7Sopenharmony_ci description = parseStringLiteral(m_curTokenStr.c_str()); 940e5c31af7Sopenharmony_ci advanceToken(); 941e5c31af7Sopenharmony_ci } 942e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_EXPECT) 943e5c31af7Sopenharmony_ci { 944e5c31af7Sopenharmony_ci advanceToken(); 945e5c31af7Sopenharmony_ci assumeToken(TOKEN_IDENTIFIER); 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_ci if (m_curTokenStr == "pass") 948e5c31af7Sopenharmony_ci expectResult = ShaderCase::EXPECT_PASS; 949e5c31af7Sopenharmony_ci else if (m_curTokenStr == "compile_fail") 950e5c31af7Sopenharmony_ci expectResult = ShaderCase::EXPECT_COMPILE_FAIL; 951e5c31af7Sopenharmony_ci else if (m_curTokenStr == "link_fail") 952e5c31af7Sopenharmony_ci expectResult = ShaderCase::EXPECT_LINK_FAIL; 953e5c31af7Sopenharmony_ci else 954e5c31af7Sopenharmony_ci parseError(string("invalid expected result value: " + m_curTokenStr)); 955e5c31af7Sopenharmony_ci 956e5c31af7Sopenharmony_ci advanceToken(); 957e5c31af7Sopenharmony_ci } 958e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_VALUES) 959e5c31af7Sopenharmony_ci { 960e5c31af7Sopenharmony_ci ShaderCase::ValueBlock block; 961e5c31af7Sopenharmony_ci parseValueBlock(block); 962e5c31af7Sopenharmony_ci valueBlockList.push_back(block); 963e5c31af7Sopenharmony_ci } 964e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_BOTH || m_curToken == TOKEN_VERTEX || m_curToken == TOKEN_FRAGMENT) 965e5c31af7Sopenharmony_ci { 966e5c31af7Sopenharmony_ci Token token = m_curToken; 967e5c31af7Sopenharmony_ci advanceToken(); 968e5c31af7Sopenharmony_ci assumeToken(TOKEN_SHADER_SOURCE); 969e5c31af7Sopenharmony_ci string source = parseShaderSource(m_curTokenStr.c_str()); 970e5c31af7Sopenharmony_ci advanceToken(); 971e5c31af7Sopenharmony_ci switch (token) 972e5c31af7Sopenharmony_ci { 973e5c31af7Sopenharmony_ci case TOKEN_BOTH: 974e5c31af7Sopenharmony_ci bothSource = source; 975e5c31af7Sopenharmony_ci break; 976e5c31af7Sopenharmony_ci case TOKEN_VERTEX: 977e5c31af7Sopenharmony_ci vertexSource = source; 978e5c31af7Sopenharmony_ci break; 979e5c31af7Sopenharmony_ci case TOKEN_FRAGMENT: 980e5c31af7Sopenharmony_ci fragmentSource = source; 981e5c31af7Sopenharmony_ci break; 982e5c31af7Sopenharmony_ci default: 983e5c31af7Sopenharmony_ci DE_ASSERT(DE_FALSE); 984e5c31af7Sopenharmony_ci } 985e5c31af7Sopenharmony_ci } 986e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_VERSION) 987e5c31af7Sopenharmony_ci { 988e5c31af7Sopenharmony_ci advanceToken(); 989e5c31af7Sopenharmony_ci 990e5c31af7Sopenharmony_ci int versionNum = 0; 991e5c31af7Sopenharmony_ci std::string postfix = ""; 992e5c31af7Sopenharmony_ci 993e5c31af7Sopenharmony_ci assumeToken(TOKEN_INT_LITERAL); 994e5c31af7Sopenharmony_ci versionNum = (int)parseIntLiteral(m_curTokenStr.c_str()); 995e5c31af7Sopenharmony_ci advanceToken(); 996e5c31af7Sopenharmony_ci 997e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_IDENTIFIER) 998e5c31af7Sopenharmony_ci { 999e5c31af7Sopenharmony_ci postfix = m_curTokenStr; 1000e5c31af7Sopenharmony_ci advanceToken(); 1001e5c31af7Sopenharmony_ci } 1002e5c31af7Sopenharmony_ci 1003e5c31af7Sopenharmony_ci if (versionNum == 100 && postfix == "es") 1004e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_100_ES; 1005e5c31af7Sopenharmony_ci else if (versionNum == 300 && postfix == "es") 1006e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_300_ES; 1007e5c31af7Sopenharmony_ci else if (versionNum == 310 && postfix == "es") 1008e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_310_ES; 1009e5c31af7Sopenharmony_ci else if (versionNum == 130) 1010e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_130; 1011e5c31af7Sopenharmony_ci else if (versionNum == 140) 1012e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_140; 1013e5c31af7Sopenharmony_ci else if (versionNum == 150) 1014e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_150; 1015e5c31af7Sopenharmony_ci else if (versionNum == 330) 1016e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_330; 1017e5c31af7Sopenharmony_ci else if (versionNum == 400) 1018e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_400; 1019e5c31af7Sopenharmony_ci else if (versionNum == 410) 1020e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_410; 1021e5c31af7Sopenharmony_ci else if (versionNum == 420) 1022e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_420; 1023e5c31af7Sopenharmony_ci else if (versionNum == 430) 1024e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_430; 1025e5c31af7Sopenharmony_ci else if (versionNum == 440) 1026e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_440; 1027e5c31af7Sopenharmony_ci else if (versionNum == 450) 1028e5c31af7Sopenharmony_ci version = glu::GLSL_VERSION_450; 1029e5c31af7Sopenharmony_ci else 1030e5c31af7Sopenharmony_ci parseError("Unknown GLSL version"); 1031e5c31af7Sopenharmony_ci } 1032e5c31af7Sopenharmony_ci else 1033e5c31af7Sopenharmony_ci parseError(string("unexpected token while parsing shader case: " + m_curTokenStr)); 1034e5c31af7Sopenharmony_ci } 1035e5c31af7Sopenharmony_ci 1036e5c31af7Sopenharmony_ci advanceToken(TOKEN_END); // case end 1037e5c31af7Sopenharmony_ci 1038e5c31af7Sopenharmony_ci if (bothSource.length() > 0) 1039e5c31af7Sopenharmony_ci { 1040e5c31af7Sopenharmony_ci DE_ASSERT(vertexSource.length() == 0); 1041e5c31af7Sopenharmony_ci DE_ASSERT(fragmentSource.length() == 0); 1042e5c31af7Sopenharmony_ci 1043e5c31af7Sopenharmony_ci string vertName = caseName + "_vertex"; 1044e5c31af7Sopenharmony_ci string fragName = caseName + "_fragment"; 1045e5c31af7Sopenharmony_ci shaderNodeList.push_back(new ShaderCase(m_testCtx, m_renderCtx, vertName.c_str(), description.c_str(), 1046e5c31af7Sopenharmony_ci expectResult, valueBlockList, version, bothSource.c_str(), DE_NULL)); 1047e5c31af7Sopenharmony_ci shaderNodeList.push_back(new ShaderCase(m_testCtx, m_renderCtx, fragName.c_str(), description.c_str(), 1048e5c31af7Sopenharmony_ci expectResult, valueBlockList, version, DE_NULL, bothSource.c_str())); 1049e5c31af7Sopenharmony_ci } 1050e5c31af7Sopenharmony_ci else 1051e5c31af7Sopenharmony_ci { 1052e5c31af7Sopenharmony_ci shaderNodeList.push_back(new ShaderCase(m_testCtx, m_renderCtx, caseName.c_str(), description.c_str(), 1053e5c31af7Sopenharmony_ci expectResult, valueBlockList, version, vertexSource.c_str(), 1054e5c31af7Sopenharmony_ci fragmentSource.c_str())); 1055e5c31af7Sopenharmony_ci } 1056e5c31af7Sopenharmony_ci} 1057e5c31af7Sopenharmony_ci 1058e5c31af7Sopenharmony_civoid ShaderParser::parseShaderGroup(vector<tcu::TestNode*>& shaderNodeList) 1059e5c31af7Sopenharmony_ci{ 1060e5c31af7Sopenharmony_ci // Parse 'case'. 1061e5c31af7Sopenharmony_ci PARSE_DBG((" parseShaderGroup()\n")); 1062e5c31af7Sopenharmony_ci advanceToken(TOKEN_GROUP); 1063e5c31af7Sopenharmony_ci 1064e5c31af7Sopenharmony_ci // Parse case name. 1065e5c31af7Sopenharmony_ci string name = m_curTokenStr; 1066e5c31af7Sopenharmony_ci advanceToken(); // \note [pyry] We don't want to check token type here (for instance to allow "uniform") group. 1067e5c31af7Sopenharmony_ci 1068e5c31af7Sopenharmony_ci // Parse description. 1069e5c31af7Sopenharmony_ci assumeToken(TOKEN_STRING); 1070e5c31af7Sopenharmony_ci string description = parseStringLiteral(m_curTokenStr.c_str()); 1071e5c31af7Sopenharmony_ci advanceToken(TOKEN_STRING); 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ci std::vector<tcu::TestNode*> children; 1074e5c31af7Sopenharmony_ci 1075e5c31af7Sopenharmony_ci // Parse group children. 1076e5c31af7Sopenharmony_ci for (;;) 1077e5c31af7Sopenharmony_ci { 1078e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_END) 1079e5c31af7Sopenharmony_ci break; 1080e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_GROUP) 1081e5c31af7Sopenharmony_ci parseShaderGroup(children); 1082e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_CASE) 1083e5c31af7Sopenharmony_ci parseShaderCase(children); 1084e5c31af7Sopenharmony_ci else 1085e5c31af7Sopenharmony_ci parseError(string("unexpected token while parsing shader group: " + m_curTokenStr)); 1086e5c31af7Sopenharmony_ci } 1087e5c31af7Sopenharmony_ci 1088e5c31af7Sopenharmony_ci advanceToken(TOKEN_END); // group end 1089e5c31af7Sopenharmony_ci 1090e5c31af7Sopenharmony_ci // Create group node. 1091e5c31af7Sopenharmony_ci tcu::TestCaseGroup* groupNode = new tcu::TestCaseGroup(m_testCtx, name.c_str(), description.c_str(), children); 1092e5c31af7Sopenharmony_ci shaderNodeList.push_back(groupNode); 1093e5c31af7Sopenharmony_ci} 1094e5c31af7Sopenharmony_ci 1095e5c31af7Sopenharmony_civector<tcu::TestNode*> ShaderParser::parse(const char* input) 1096e5c31af7Sopenharmony_ci{ 1097e5c31af7Sopenharmony_ci // Initialize parser. 1098e5c31af7Sopenharmony_ci m_input = input; 1099e5c31af7Sopenharmony_ci m_curPtr = m_input.c_str(); 1100e5c31af7Sopenharmony_ci m_curToken = TOKEN_INVALID; 1101e5c31af7Sopenharmony_ci m_curTokenStr = ""; 1102e5c31af7Sopenharmony_ci advanceToken(); 1103e5c31af7Sopenharmony_ci 1104e5c31af7Sopenharmony_ci vector<tcu::TestNode*> nodeList; 1105e5c31af7Sopenharmony_ci 1106e5c31af7Sopenharmony_ci // Parse all cases. 1107e5c31af7Sopenharmony_ci PARSE_DBG(("parse()\n")); 1108e5c31af7Sopenharmony_ci for (;;) 1109e5c31af7Sopenharmony_ci { 1110e5c31af7Sopenharmony_ci if (m_curToken == TOKEN_CASE) 1111e5c31af7Sopenharmony_ci parseShaderCase(nodeList); 1112e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_GROUP) 1113e5c31af7Sopenharmony_ci parseShaderGroup(nodeList); 1114e5c31af7Sopenharmony_ci else if (m_curToken == TOKEN_EOF) 1115e5c31af7Sopenharmony_ci break; 1116e5c31af7Sopenharmony_ci else 1117e5c31af7Sopenharmony_ci parseError(string("invalid token encountered at main level: '") + m_curTokenStr + "'"); 1118e5c31af7Sopenharmony_ci } 1119e5c31af7Sopenharmony_ci 1120e5c31af7Sopenharmony_ci assumeToken(TOKEN_EOF); 1121e5c31af7Sopenharmony_ci // printf(" parsed %d test cases.\n", caseList.size()); 1122e5c31af7Sopenharmony_ci return nodeList; 1123e5c31af7Sopenharmony_ci} 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_ci} // sl 1126e5c31af7Sopenharmony_ci 1127e5c31af7Sopenharmony_ciShaderLibrary::ShaderLibrary(tcu::TestContext& testCtx, RenderContext& renderCtx) 1128e5c31af7Sopenharmony_ci : m_testCtx(testCtx), m_renderCtx(renderCtx) 1129e5c31af7Sopenharmony_ci{ 1130e5c31af7Sopenharmony_ci} 1131e5c31af7Sopenharmony_ci 1132e5c31af7Sopenharmony_ciShaderLibrary::~ShaderLibrary(void) 1133e5c31af7Sopenharmony_ci{ 1134e5c31af7Sopenharmony_ci} 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_civector<tcu::TestNode*> ShaderLibrary::loadShaderFile(const char* fileName) 1137e5c31af7Sopenharmony_ci{ 1138e5c31af7Sopenharmony_ci tcu::Resource* resource = m_testCtx.getArchive().getResource(fileName); 1139e5c31af7Sopenharmony_ci std::vector<char> buf; 1140e5c31af7Sopenharmony_ci 1141e5c31af7Sopenharmony_ci /* printf(" loading '%s'\n", fileName);*/ 1142e5c31af7Sopenharmony_ci 1143e5c31af7Sopenharmony_ci try 1144e5c31af7Sopenharmony_ci { 1145e5c31af7Sopenharmony_ci int size = resource->getSize(); 1146e5c31af7Sopenharmony_ci buf.resize(size + 1); 1147e5c31af7Sopenharmony_ci resource->read((deUint8*)&buf[0], size); 1148e5c31af7Sopenharmony_ci buf[size] = '\0'; 1149e5c31af7Sopenharmony_ci } 1150e5c31af7Sopenharmony_ci catch (const std::exception&) 1151e5c31af7Sopenharmony_ci { 1152e5c31af7Sopenharmony_ci delete resource; 1153e5c31af7Sopenharmony_ci throw; 1154e5c31af7Sopenharmony_ci } 1155e5c31af7Sopenharmony_ci 1156e5c31af7Sopenharmony_ci delete resource; 1157e5c31af7Sopenharmony_ci 1158e5c31af7Sopenharmony_ci sl::ShaderParser parser(m_testCtx, m_renderCtx); 1159e5c31af7Sopenharmony_ci vector<tcu::TestNode*> nodes = parser.parse(&buf[0]); 1160e5c31af7Sopenharmony_ci 1161e5c31af7Sopenharmony_ci return nodes; 1162e5c31af7Sopenharmony_ci} 1163e5c31af7Sopenharmony_ci 1164e5c31af7Sopenharmony_ci// ShaderLibraryGroup 1165e5c31af7Sopenharmony_ci 1166e5c31af7Sopenharmony_ciShaderLibraryGroup::ShaderLibraryGroup(Context& context, const char* name, const char* description, 1167e5c31af7Sopenharmony_ci const char* filename) 1168e5c31af7Sopenharmony_ci : TestCaseGroup(context, name, description), m_filename(filename) 1169e5c31af7Sopenharmony_ci{ 1170e5c31af7Sopenharmony_ci} 1171e5c31af7Sopenharmony_ci 1172e5c31af7Sopenharmony_ciShaderLibraryGroup::~ShaderLibraryGroup(void) 1173e5c31af7Sopenharmony_ci{ 1174e5c31af7Sopenharmony_ci} 1175e5c31af7Sopenharmony_ci 1176e5c31af7Sopenharmony_civoid ShaderLibraryGroup::init(void) 1177e5c31af7Sopenharmony_ci{ 1178e5c31af7Sopenharmony_ci deqp::ShaderLibrary shaderLibrary(m_testCtx, m_context.getRenderContext()); 1179e5c31af7Sopenharmony_ci std::vector<tcu::TestNode*> children = shaderLibrary.loadShaderFile(m_filename.c_str()); 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ci for (int i = 0; i < (int)children.size(); i++) 1182e5c31af7Sopenharmony_ci addChild(children[i]); 1183e5c31af7Sopenharmony_ci} 1184e5c31af7Sopenharmony_ci 1185e5c31af7Sopenharmony_ci} // deqp 1186