1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Test Executor 3e5c31af7Sopenharmony_ci * ------------------------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Test case result parser. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "xeTestResultParser.hpp" 25e5c31af7Sopenharmony_ci#include "xeTestCaseResult.hpp" 26e5c31af7Sopenharmony_ci#include "xeBatchResult.hpp" 27e5c31af7Sopenharmony_ci#include "deString.h" 28e5c31af7Sopenharmony_ci#include "deInt32.h" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include <sstream> 31e5c31af7Sopenharmony_ci#include <stdlib.h> 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ciusing std::string; 34e5c31af7Sopenharmony_ciusing std::vector; 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_cinamespace xe 37e5c31af7Sopenharmony_ci{ 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cistatic inline int toInt (const char* str) 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci return atoi(str); 42e5c31af7Sopenharmony_ci} 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_cistatic inline double toDouble (const char* str) 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_ci return atof(str); 47e5c31af7Sopenharmony_ci} 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cistatic inline deInt64 toInt64 (const char* str) 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci std::istringstream s (str); 52e5c31af7Sopenharmony_ci deInt64 val; 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_ci s >> val; 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ci return val; 57e5c31af7Sopenharmony_ci} 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_cistatic inline bool toBool (const char* str) 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_ci return deStringEqual(str, "OK") || deStringEqual(str, "True"); 62e5c31af7Sopenharmony_ci} 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_cistatic const char* stripLeadingWhitespace (const char* str) 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_ci int whitespaceCount = 0; 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ci while (str[whitespaceCount] != 0 && 69e5c31af7Sopenharmony_ci (str[whitespaceCount] == ' ' || 70e5c31af7Sopenharmony_ci str[whitespaceCount] == '\t' || 71e5c31af7Sopenharmony_ci str[whitespaceCount] == '\r' || 72e5c31af7Sopenharmony_ci str[whitespaceCount] == '\n')) 73e5c31af7Sopenharmony_ci whitespaceCount += 1; 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci return str + whitespaceCount; 76e5c31af7Sopenharmony_ci} 77e5c31af7Sopenharmony_ci 78e5c31af7Sopenharmony_cistruct EnumMapEntry 79e5c31af7Sopenharmony_ci{ 80e5c31af7Sopenharmony_ci deUint32 hash; 81e5c31af7Sopenharmony_ci const char* name; 82e5c31af7Sopenharmony_ci int value; 83e5c31af7Sopenharmony_ci}; 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_cistatic const EnumMapEntry s_statusCodeMap[] = 86e5c31af7Sopenharmony_ci{ 87e5c31af7Sopenharmony_ci { 0x7c8a99bc, "Pass", TESTSTATUSCODE_PASS }, 88e5c31af7Sopenharmony_ci { 0x7c851ca1, "Fail", TESTSTATUSCODE_FAIL }, 89e5c31af7Sopenharmony_ci { 0x10ecd324, "QualityWarning", TESTSTATUSCODE_QUALITY_WARNING }, 90e5c31af7Sopenharmony_ci { 0x341ae835, "CompatibilityWarning", TESTSTATUSCODE_COMPATIBILITY_WARNING }, 91e5c31af7Sopenharmony_ci { 0x058acbca, "Pending", TESTSTATUSCODE_PENDING }, 92e5c31af7Sopenharmony_ci { 0xc4d74b26, "Running", TESTSTATUSCODE_RUNNING }, 93e5c31af7Sopenharmony_ci { 0x6409f93c, "NotSupported", TESTSTATUSCODE_NOT_SUPPORTED }, 94e5c31af7Sopenharmony_ci { 0xfa5a9ab7, "ResourceError", TESTSTATUSCODE_RESOURCE_ERROR }, 95e5c31af7Sopenharmony_ci { 0xad6793ec, "InternalError", TESTSTATUSCODE_INTERNAL_ERROR }, 96e5c31af7Sopenharmony_ci { 0x838f3034, "Canceled", TESTSTATUSCODE_CANCELED }, 97e5c31af7Sopenharmony_ci { 0x42b6efac, "Timeout", TESTSTATUSCODE_TIMEOUT }, 98e5c31af7Sopenharmony_ci { 0x0cfb98f6, "Crash", TESTSTATUSCODE_CRASH }, 99e5c31af7Sopenharmony_ci { 0xe326e01d, "Disabled", TESTSTATUSCODE_DISABLED }, 100e5c31af7Sopenharmony_ci { 0x77061af2, "Terminated", TESTSTATUSCODE_TERMINATED }, 101e5c31af7Sopenharmony_ci { 0xd9e6b393, "Waiver", TESTSTATUSCODE_WAIVER } 102e5c31af7Sopenharmony_ci}; 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_cistatic const EnumMapEntry s_resultItemMap[] = 105e5c31af7Sopenharmony_ci{ 106e5c31af7Sopenharmony_ci { 0xce8ac2e4, "Result", ri::TYPE_RESULT }, 107e5c31af7Sopenharmony_ci { 0x7c8cdcea, "Text", ri::TYPE_TEXT }, 108e5c31af7Sopenharmony_ci { 0xc6540c6e, "Number", ri::TYPE_NUMBER }, 109e5c31af7Sopenharmony_ci { 0x0d656c88, "Image", ri::TYPE_IMAGE }, 110e5c31af7Sopenharmony_ci { 0x8ac9ee14, "ImageSet", ri::TYPE_IMAGESET }, 111e5c31af7Sopenharmony_ci { 0x1181fa5a, "VertexShader", ri::TYPE_SHADER }, 112e5c31af7Sopenharmony_ci { 0xa93daef0, "FragmentShader", ri::TYPE_SHADER }, 113e5c31af7Sopenharmony_ci { 0x8f066128, "GeometryShader", ri::TYPE_SHADER }, 114e5c31af7Sopenharmony_ci { 0x235a931c, "TessControlShader", ri::TYPE_SHADER }, 115e5c31af7Sopenharmony_ci { 0xa1bf7153, "TessEvaluationShader", ri::TYPE_SHADER }, 116e5c31af7Sopenharmony_ci { 0x6c1415d9, "ComputeShader", ri::TYPE_SHADER }, 117e5c31af7Sopenharmony_ci { 0x68738b22, "RaygenShader", ri::TYPE_SHADER }, 118e5c31af7Sopenharmony_ci { 0x51d29ce9, "AnyHitShader", ri::TYPE_SHADER }, 119e5c31af7Sopenharmony_ci { 0x8c64a6be, "ClosestHitShader", ri::TYPE_SHADER }, 120e5c31af7Sopenharmony_ci { 0xb30ed398, "MissShader", ri::TYPE_SHADER }, 121e5c31af7Sopenharmony_ci { 0x26150e53, "IntersectionShader", ri::TYPE_SHADER }, 122e5c31af7Sopenharmony_ci { 0x7e50944c, "CallableShader", ri::TYPE_SHADER }, 123e5c31af7Sopenharmony_ci { 0x925c7349, "MeshShader", ri::TYPE_SHADER }, 124e5c31af7Sopenharmony_ci { 0xc3a35d6f, "TaskShader", ri::TYPE_SHADER }, 125e5c31af7Sopenharmony_ci { 0x72863a54, "ShaderProgram", ri::TYPE_SHADERPROGRAM }, 126e5c31af7Sopenharmony_ci { 0xb4efc08d, "ShaderSource", ri::TYPE_SHADERSOURCE }, 127e5c31af7Sopenharmony_ci { 0xaee4380a, "SpirVAssemblySource", ri::TYPE_SPIRVSOURCE }, 128e5c31af7Sopenharmony_ci { 0xff265913, "InfoLog", ri::TYPE_INFOLOG }, 129e5c31af7Sopenharmony_ci { 0x84159b73, "EglConfig", ri::TYPE_EGLCONFIG }, 130e5c31af7Sopenharmony_ci { 0xdd34391f, "EglConfigSet", ri::TYPE_EGLCONFIGSET }, 131e5c31af7Sopenharmony_ci { 0xebbb3aba, "Section", ri::TYPE_SECTION }, 132e5c31af7Sopenharmony_ci { 0xa0f15677, "KernelSource", ri::TYPE_KERNELSOURCE }, 133e5c31af7Sopenharmony_ci { 0x1ee9083a, "CompileInfo", ri::TYPE_COMPILEINFO }, 134e5c31af7Sopenharmony_ci { 0xf1004023, "SampleList", ri::TYPE_SAMPLELIST }, 135e5c31af7Sopenharmony_ci { 0xf0feae93, "SampleInfo", ri::TYPE_SAMPLEINFO }, 136e5c31af7Sopenharmony_ci { 0x2aa6f14e, "ValueInfo", ri::TYPE_VALUEINFO }, 137e5c31af7Sopenharmony_ci { 0xd09429e7, "Sample", ri::TYPE_SAMPLE }, 138e5c31af7Sopenharmony_ci { 0x0e4a4722, "Value", ri::TYPE_SAMPLEVALUE } 139e5c31af7Sopenharmony_ci}; 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_cistatic const EnumMapEntry s_imageFormatMap[] = 142e5c31af7Sopenharmony_ci{ 143e5c31af7Sopenharmony_ci { 0xcc4ffac8, "RGB888", ri::Image::FORMAT_RGB888 }, 144e5c31af7Sopenharmony_ci { 0x20dcb0c1, "RGBA8888", ri::Image::FORMAT_RGBA8888 } 145e5c31af7Sopenharmony_ci}; 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_cistatic const EnumMapEntry s_compressionMap[] = 148e5c31af7Sopenharmony_ci{ 149e5c31af7Sopenharmony_ci { 0x7c89bbd5, "None", ri::Image::COMPRESSION_NONE }, 150e5c31af7Sopenharmony_ci { 0x0b88118a, "PNG", ri::Image::COMPRESSION_PNG } 151e5c31af7Sopenharmony_ci}; 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_cistatic const EnumMapEntry s_shaderTypeFromTagMap[] = 154e5c31af7Sopenharmony_ci{ 155e5c31af7Sopenharmony_ci { 0x1181fa5a, "VertexShader", ri::Shader::SHADERTYPE_VERTEX }, 156e5c31af7Sopenharmony_ci { 0xa93daef0, "FragmentShader", ri::Shader::SHADERTYPE_FRAGMENT }, 157e5c31af7Sopenharmony_ci { 0x8f066128, "GeometryShader", ri::Shader::SHADERTYPE_GEOMETRY }, 158e5c31af7Sopenharmony_ci { 0x235a931c, "TessControlShader", ri::Shader::SHADERTYPE_TESS_CONTROL }, 159e5c31af7Sopenharmony_ci { 0xa1bf7153, "TessEvaluationShader", ri::Shader::SHADERTYPE_TESS_EVALUATION }, 160e5c31af7Sopenharmony_ci { 0x6c1415d9, "ComputeShader", ri::Shader::SHADERTYPE_COMPUTE }, 161e5c31af7Sopenharmony_ci { 0x68738b22, "RaygenShader", ri::Shader::SHADERTYPE_RAYGEN }, 162e5c31af7Sopenharmony_ci { 0x51d29ce9, "AnyHitShader", ri::Shader::SHADERTYPE_ANY_HIT }, 163e5c31af7Sopenharmony_ci { 0x8c64a6be, "ClosestHitShader", ri::Shader::SHADERTYPE_CLOSEST_HIT }, 164e5c31af7Sopenharmony_ci { 0xb30ed398, "MissShader", ri::Shader::SHADERTYPE_MISS }, 165e5c31af7Sopenharmony_ci { 0x26150e53, "IntersectionShader", ri::Shader::SHADERTYPE_INTERSECTION }, 166e5c31af7Sopenharmony_ci { 0x7e50944c, "CallableShader", ri::Shader::SHADERTYPE_CALLABLE }, 167e5c31af7Sopenharmony_ci { 0xc3a35d6f, "TaskShader", ri::Shader::SHADERTYPE_TASK }, 168e5c31af7Sopenharmony_ci { 0x925c7349, "MeshShader", ri::Shader::SHADERTYPE_MESH }, 169e5c31af7Sopenharmony_ci}; 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_cistatic const EnumMapEntry s_testTypeMap[] = 172e5c31af7Sopenharmony_ci{ 173e5c31af7Sopenharmony_ci { 0x7fa80959, "SelfValidate", TESTCASETYPE_SELF_VALIDATE }, 174e5c31af7Sopenharmony_ci { 0xdb797567, "Capability", TESTCASETYPE_CAPABILITY }, 175e5c31af7Sopenharmony_ci { 0x2ca3ec10, "Accuracy", TESTCASETYPE_ACCURACY }, 176e5c31af7Sopenharmony_ci { 0xa48ac277, "Performance", TESTCASETYPE_PERFORMANCE } 177e5c31af7Sopenharmony_ci}; 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_cistatic const EnumMapEntry s_logVersionMap[] = 180e5c31af7Sopenharmony_ci{ 181e5c31af7Sopenharmony_ci { 0x0b7dac93, "0.2.0", TESTLOGVERSION_0_2_0 }, 182e5c31af7Sopenharmony_ci { 0x0b7db0d4, "0.3.0", TESTLOGVERSION_0_3_0 }, 183e5c31af7Sopenharmony_ci { 0x0b7db0d5, "0.3.1", TESTLOGVERSION_0_3_1 }, 184e5c31af7Sopenharmony_ci { 0x0b7db0d6, "0.3.2", TESTLOGVERSION_0_3_2 }, 185e5c31af7Sopenharmony_ci { 0x0b7db0d7, "0.3.3", TESTLOGVERSION_0_3_3 }, 186e5c31af7Sopenharmony_ci { 0x0b7db0d8, "0.3.4", TESTLOGVERSION_0_3_4 } 187e5c31af7Sopenharmony_ci}; 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_cistatic const EnumMapEntry s_sampleValueTagMap[] = 190e5c31af7Sopenharmony_ci{ 191e5c31af7Sopenharmony_ci { 0xddf2d0d1, "Predictor", ri::ValueInfo::VALUETAG_PREDICTOR }, 192e5c31af7Sopenharmony_ci { 0x9bee2c34, "Response", ri::ValueInfo::VALUETAG_RESPONSE }, 193e5c31af7Sopenharmony_ci}; 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci#if defined(DE_DEBUG) 196e5c31af7Sopenharmony_cistatic void printHashes (const char* name, const EnumMapEntry* entries, int numEntries) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci printf("%s:\n", name); 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numEntries; ndx++) 201e5c31af7Sopenharmony_ci printf("0x%08x\t%s\n", deStringHash(entries[ndx].name), entries[ndx].name); 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci printf("\n"); 204e5c31af7Sopenharmony_ci} 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ci#define PRINT_HASHES(MAP) printHashes(#MAP, MAP, DE_LENGTH_OF_ARRAY(MAP)) 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_civoid TestResultParser_printHashes (void) 209e5c31af7Sopenharmony_ci{ 210e5c31af7Sopenharmony_ci PRINT_HASHES(s_statusCodeMap); 211e5c31af7Sopenharmony_ci PRINT_HASHES(s_resultItemMap); 212e5c31af7Sopenharmony_ci PRINT_HASHES(s_imageFormatMap); 213e5c31af7Sopenharmony_ci PRINT_HASHES(s_compressionMap); 214e5c31af7Sopenharmony_ci PRINT_HASHES(s_shaderTypeFromTagMap); 215e5c31af7Sopenharmony_ci PRINT_HASHES(s_testTypeMap); 216e5c31af7Sopenharmony_ci PRINT_HASHES(s_logVersionMap); 217e5c31af7Sopenharmony_ci PRINT_HASHES(s_sampleValueTagMap); 218e5c31af7Sopenharmony_ci} 219e5c31af7Sopenharmony_ci#endif 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_cistatic inline int getEnumValue (const char* enumName, const EnumMapEntry* entries, int numEntries, const char* name) 222e5c31af7Sopenharmony_ci{ 223e5c31af7Sopenharmony_ci deUint32 hash = deStringHash(name); 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < numEntries; ndx++) 226e5c31af7Sopenharmony_ci { 227e5c31af7Sopenharmony_ci if (entries[ndx].hash == hash && deStringEqual(entries[ndx].name, name)) 228e5c31af7Sopenharmony_ci return entries[ndx].value; 229e5c31af7Sopenharmony_ci } 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci throw TestResultParseError(string("Could not map '") + name + "' to " + enumName); 232e5c31af7Sopenharmony_ci} 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ciTestStatusCode getTestStatusCode (const char* statusCode) 235e5c31af7Sopenharmony_ci{ 236e5c31af7Sopenharmony_ci return (TestStatusCode)getEnumValue("status code", s_statusCodeMap, DE_LENGTH_OF_ARRAY(s_statusCodeMap), statusCode); 237e5c31af7Sopenharmony_ci} 238e5c31af7Sopenharmony_ci 239e5c31af7Sopenharmony_cistatic ri::Type getResultItemType (const char* elemName) 240e5c31af7Sopenharmony_ci{ 241e5c31af7Sopenharmony_ci return (ri::Type)getEnumValue("result item type", s_resultItemMap, DE_LENGTH_OF_ARRAY(s_resultItemMap), elemName); 242e5c31af7Sopenharmony_ci} 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_cistatic ri::Image::Format getImageFormat (const char* imageFormat) 245e5c31af7Sopenharmony_ci{ 246e5c31af7Sopenharmony_ci return (ri::Image::Format)getEnumValue("image format", s_imageFormatMap, DE_LENGTH_OF_ARRAY(s_imageFormatMap), imageFormat); 247e5c31af7Sopenharmony_ci} 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_cistatic ri::Image::Compression getImageCompression (const char* compression) 250e5c31af7Sopenharmony_ci{ 251e5c31af7Sopenharmony_ci return (ri::Image::Compression)getEnumValue("image compression", s_compressionMap, DE_LENGTH_OF_ARRAY(s_compressionMap), compression); 252e5c31af7Sopenharmony_ci} 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_cistatic ri::Shader::ShaderType getShaderTypeFromTagName (const char* shaderType) 255e5c31af7Sopenharmony_ci{ 256e5c31af7Sopenharmony_ci return (ri::Shader::ShaderType)getEnumValue("shader type", s_shaderTypeFromTagMap, DE_LENGTH_OF_ARRAY(s_shaderTypeFromTagMap), shaderType); 257e5c31af7Sopenharmony_ci} 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_cistatic TestCaseType getTestCaseType (const char* caseType) 260e5c31af7Sopenharmony_ci{ 261e5c31af7Sopenharmony_ci return (TestCaseType)getEnumValue("test case type", s_testTypeMap, DE_LENGTH_OF_ARRAY(s_testTypeMap), caseType); 262e5c31af7Sopenharmony_ci} 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_cistatic TestLogVersion getTestLogVersion (const char* logVersion) 265e5c31af7Sopenharmony_ci{ 266e5c31af7Sopenharmony_ci return (TestLogVersion)getEnumValue("test log version", s_logVersionMap, DE_LENGTH_OF_ARRAY(s_logVersionMap), logVersion); 267e5c31af7Sopenharmony_ci} 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_cistatic ri::ValueInfo::ValueTag getSampleValueTag (const char* tag) 270e5c31af7Sopenharmony_ci{ 271e5c31af7Sopenharmony_ci return (ri::ValueInfo::ValueTag)getEnumValue("sample value tag", s_sampleValueTagMap, DE_LENGTH_OF_ARRAY(s_sampleValueTagMap), tag); 272e5c31af7Sopenharmony_ci} 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_cistatic TestCaseType getTestCaseTypeFromPath (const char* casePath) 275e5c31af7Sopenharmony_ci{ 276e5c31af7Sopenharmony_ci if (deStringBeginsWith(casePath, "dEQP-GLES2.")) 277e5c31af7Sopenharmony_ci { 278e5c31af7Sopenharmony_ci const char* group = casePath+11; 279e5c31af7Sopenharmony_ci if (deStringBeginsWith(group, "capability.")) 280e5c31af7Sopenharmony_ci return TESTCASETYPE_CAPABILITY; 281e5c31af7Sopenharmony_ci else if (deStringBeginsWith(group, "accuracy.")) 282e5c31af7Sopenharmony_ci return TESTCASETYPE_ACCURACY; 283e5c31af7Sopenharmony_ci else if (deStringBeginsWith(group, "performance.")) 284e5c31af7Sopenharmony_ci return TESTCASETYPE_PERFORMANCE; 285e5c31af7Sopenharmony_ci } 286e5c31af7Sopenharmony_ci 287e5c31af7Sopenharmony_ci return TESTCASETYPE_SELF_VALIDATE; 288e5c31af7Sopenharmony_ci} 289e5c31af7Sopenharmony_ci 290e5c31af7Sopenharmony_cistatic ri::NumericValue getNumericValue (const std::string& value) 291e5c31af7Sopenharmony_ci{ 292e5c31af7Sopenharmony_ci const bool isFloat = value.find('.') != std::string::npos || value.find('e') != std::string::npos; 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_ci if (isFloat) 295e5c31af7Sopenharmony_ci { 296e5c31af7Sopenharmony_ci const double num = toDouble(stripLeadingWhitespace(value.c_str())); 297e5c31af7Sopenharmony_ci return ri::NumericValue(num); 298e5c31af7Sopenharmony_ci } 299e5c31af7Sopenharmony_ci else 300e5c31af7Sopenharmony_ci { 301e5c31af7Sopenharmony_ci const deInt64 num = toInt64(stripLeadingWhitespace(value.c_str())); 302e5c31af7Sopenharmony_ci return ri::NumericValue(num); 303e5c31af7Sopenharmony_ci } 304e5c31af7Sopenharmony_ci} 305e5c31af7Sopenharmony_ci 306e5c31af7Sopenharmony_ciTestResultParser::TestResultParser (void) 307e5c31af7Sopenharmony_ci : m_result (DE_NULL) 308e5c31af7Sopenharmony_ci , m_state (STATE_NOT_INITIALIZED) 309e5c31af7Sopenharmony_ci , m_logVersion (TESTLOGVERSION_LAST) 310e5c31af7Sopenharmony_ci , m_curItemList (DE_NULL) 311e5c31af7Sopenharmony_ci , m_base64DecodeOffset (0) 312e5c31af7Sopenharmony_ci{ 313e5c31af7Sopenharmony_ci} 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ciTestResultParser::~TestResultParser (void) 316e5c31af7Sopenharmony_ci{ 317e5c31af7Sopenharmony_ci} 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_civoid TestResultParser::clear (void) 320e5c31af7Sopenharmony_ci{ 321e5c31af7Sopenharmony_ci m_xmlParser.clear(); 322e5c31af7Sopenharmony_ci m_itemStack.clear(); 323e5c31af7Sopenharmony_ci 324e5c31af7Sopenharmony_ci m_result = DE_NULL; 325e5c31af7Sopenharmony_ci m_state = STATE_NOT_INITIALIZED; 326e5c31af7Sopenharmony_ci m_logVersion = TESTLOGVERSION_LAST; 327e5c31af7Sopenharmony_ci m_curItemList = DE_NULL; 328e5c31af7Sopenharmony_ci m_base64DecodeOffset = 0; 329e5c31af7Sopenharmony_ci m_curNumValue.clear(); 330e5c31af7Sopenharmony_ci} 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_civoid TestResultParser::init (TestCaseResult* dstResult) 333e5c31af7Sopenharmony_ci{ 334e5c31af7Sopenharmony_ci clear(); 335e5c31af7Sopenharmony_ci m_result = dstResult; 336e5c31af7Sopenharmony_ci m_state = STATE_INITIALIZED; 337e5c31af7Sopenharmony_ci m_curItemList = &dstResult->resultItems; 338e5c31af7Sopenharmony_ci} 339e5c31af7Sopenharmony_ci 340e5c31af7Sopenharmony_ciTestResultParser::ParseResult TestResultParser::parse (const deUint8* bytes, int numBytes) 341e5c31af7Sopenharmony_ci{ 342e5c31af7Sopenharmony_ci DE_ASSERT(m_result && m_state != STATE_NOT_INITIALIZED); 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci try 345e5c31af7Sopenharmony_ci { 346e5c31af7Sopenharmony_ci bool resultChanged = false; 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci m_xmlParser.feed(bytes, numBytes); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci for (;;) 351e5c31af7Sopenharmony_ci { 352e5c31af7Sopenharmony_ci xml::Element curElement = m_xmlParser.getElement(); 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_ci if (curElement == xml::ELEMENT_INCOMPLETE || 355e5c31af7Sopenharmony_ci curElement == xml::ELEMENT_END_OF_STRING) 356e5c31af7Sopenharmony_ci break; 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci switch (curElement) 359e5c31af7Sopenharmony_ci { 360e5c31af7Sopenharmony_ci case xml::ELEMENT_START: handleElementStart(); break; 361e5c31af7Sopenharmony_ci case xml::ELEMENT_END: handleElementEnd(); break; 362e5c31af7Sopenharmony_ci case xml::ELEMENT_DATA: handleData(); break; 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ci default: 365e5c31af7Sopenharmony_ci DE_ASSERT(false); 366e5c31af7Sopenharmony_ci } 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci resultChanged = true; 369e5c31af7Sopenharmony_ci m_xmlParser.advance(); 370e5c31af7Sopenharmony_ci } 371e5c31af7Sopenharmony_ci 372e5c31af7Sopenharmony_ci if (m_xmlParser.getElement() == xml::ELEMENT_END_OF_STRING) 373e5c31af7Sopenharmony_ci { 374e5c31af7Sopenharmony_ci if (m_state != STATE_TEST_CASE_RESULT_ENDED) 375e5c31af7Sopenharmony_ci throw TestResultParseError("Unexpected end of log data"); 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci return PARSERESULT_COMPLETE; 378e5c31af7Sopenharmony_ci } 379e5c31af7Sopenharmony_ci else 380e5c31af7Sopenharmony_ci return resultChanged ? PARSERESULT_CHANGED 381e5c31af7Sopenharmony_ci : PARSERESULT_NOT_CHANGED; 382e5c31af7Sopenharmony_ci } 383e5c31af7Sopenharmony_ci catch (const TestResultParseError& e) 384e5c31af7Sopenharmony_ci { 385e5c31af7Sopenharmony_ci // Set error code to result. 386e5c31af7Sopenharmony_ci m_result->statusCode = TESTSTATUSCODE_INTERNAL_ERROR; 387e5c31af7Sopenharmony_ci m_result->statusDetails = e.what(); 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci return PARSERESULT_ERROR; 390e5c31af7Sopenharmony_ci } 391e5c31af7Sopenharmony_ci catch (const xml::ParseError& e) 392e5c31af7Sopenharmony_ci { 393e5c31af7Sopenharmony_ci // Set error code to result. 394e5c31af7Sopenharmony_ci m_result->statusCode = TESTSTATUSCODE_INTERNAL_ERROR; 395e5c31af7Sopenharmony_ci m_result->statusDetails = e.what(); 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci return PARSERESULT_ERROR; 398e5c31af7Sopenharmony_ci } 399e5c31af7Sopenharmony_ci} 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ciconst char* TestResultParser::getAttribute (const char* name) 402e5c31af7Sopenharmony_ci{ 403e5c31af7Sopenharmony_ci if (!m_xmlParser.hasAttribute(name)) 404e5c31af7Sopenharmony_ci throw TestResultParseError(string("Missing attribute '") + name + "' in <" + m_xmlParser.getElementName() + ">"); 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci return m_xmlParser.getAttribute(name); 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ciri::Item* TestResultParser::getCurrentItem (void) 410e5c31af7Sopenharmony_ci{ 411e5c31af7Sopenharmony_ci return !m_itemStack.empty() ? m_itemStack.back() : DE_NULL; 412e5c31af7Sopenharmony_ci} 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ciri::List* TestResultParser::getCurrentItemList (void) 415e5c31af7Sopenharmony_ci{ 416e5c31af7Sopenharmony_ci DE_ASSERT(m_curItemList); 417e5c31af7Sopenharmony_ci return m_curItemList; 418e5c31af7Sopenharmony_ci} 419e5c31af7Sopenharmony_ci 420e5c31af7Sopenharmony_civoid TestResultParser::updateCurrentItemList (void) 421e5c31af7Sopenharmony_ci{ 422e5c31af7Sopenharmony_ci m_curItemList = DE_NULL; 423e5c31af7Sopenharmony_ci 424e5c31af7Sopenharmony_ci for (vector<ri::Item*>::reverse_iterator i = m_itemStack.rbegin(); i != m_itemStack.rend(); i++) 425e5c31af7Sopenharmony_ci { 426e5c31af7Sopenharmony_ci ri::Item* item = *i; 427e5c31af7Sopenharmony_ci ri::Type type = item->getType(); 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci if (type == ri::TYPE_IMAGESET) 430e5c31af7Sopenharmony_ci m_curItemList = &static_cast<ri::ImageSet*>(item)->images; 431e5c31af7Sopenharmony_ci else if (type == ri::TYPE_SECTION) 432e5c31af7Sopenharmony_ci m_curItemList = &static_cast<ri::Section*>(item)->items; 433e5c31af7Sopenharmony_ci else if (type == ri::TYPE_EGLCONFIGSET) 434e5c31af7Sopenharmony_ci m_curItemList = &static_cast<ri::EglConfigSet*>(item)->configs; 435e5c31af7Sopenharmony_ci else if (type == ri::TYPE_SHADERPROGRAM) 436e5c31af7Sopenharmony_ci m_curItemList = &static_cast<ri::ShaderProgram*>(item)->shaders; 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci if (m_curItemList) 439e5c31af7Sopenharmony_ci break; 440e5c31af7Sopenharmony_ci } 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ci if (!m_curItemList) 443e5c31af7Sopenharmony_ci m_curItemList = &m_result->resultItems; 444e5c31af7Sopenharmony_ci} 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_civoid TestResultParser::pushItem (ri::Item* item) 447e5c31af7Sopenharmony_ci{ 448e5c31af7Sopenharmony_ci m_itemStack.push_back(item); 449e5c31af7Sopenharmony_ci updateCurrentItemList(); 450e5c31af7Sopenharmony_ci} 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_civoid TestResultParser::popItem (void) 453e5c31af7Sopenharmony_ci{ 454e5c31af7Sopenharmony_ci m_itemStack.pop_back(); 455e5c31af7Sopenharmony_ci updateCurrentItemList(); 456e5c31af7Sopenharmony_ci} 457e5c31af7Sopenharmony_ci 458e5c31af7Sopenharmony_civoid TestResultParser::handleElementStart (void) 459e5c31af7Sopenharmony_ci{ 460e5c31af7Sopenharmony_ci const char* elemName = m_xmlParser.getElementName(); 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ci if (m_state == STATE_INITIALIZED) 463e5c31af7Sopenharmony_ci { 464e5c31af7Sopenharmony_ci // Expect TestCaseResult. 465e5c31af7Sopenharmony_ci if (!deStringEqual(elemName, "TestCaseResult")) 466e5c31af7Sopenharmony_ci throw TestResultParseError(string("Expected <TestCaseResult>, got <") + elemName + ">"); 467e5c31af7Sopenharmony_ci 468e5c31af7Sopenharmony_ci const char* version = getAttribute("Version"); 469e5c31af7Sopenharmony_ci m_logVersion = getTestLogVersion(version); 470e5c31af7Sopenharmony_ci // \note Currently assumed that all known log versions are supported. 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_ci m_result->caseVersion = version; 473e5c31af7Sopenharmony_ci m_result->casePath = getAttribute("CasePath"); 474e5c31af7Sopenharmony_ci m_result->caseType = TESTCASETYPE_SELF_VALIDATE; 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_ci if (m_xmlParser.hasAttribute("CaseType")) 477e5c31af7Sopenharmony_ci m_result->caseType = getTestCaseType(m_xmlParser.getAttribute("CaseType")); 478e5c31af7Sopenharmony_ci else 479e5c31af7Sopenharmony_ci { 480e5c31af7Sopenharmony_ci // Do guess based on path for legacy log files. 481e5c31af7Sopenharmony_ci if (m_logVersion >= TESTLOGVERSION_0_3_2) 482e5c31af7Sopenharmony_ci throw TestResultParseError("Missing CaseType attribute in <TestCaseResult>"); 483e5c31af7Sopenharmony_ci m_result->caseType = getTestCaseTypeFromPath(m_result->casePath.c_str()); 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci m_state = STATE_IN_TEST_CASE_RESULT; 487e5c31af7Sopenharmony_ci } 488e5c31af7Sopenharmony_ci else 489e5c31af7Sopenharmony_ci { 490e5c31af7Sopenharmony_ci ri::List* curList = getCurrentItemList(); 491e5c31af7Sopenharmony_ci ri::Type itemType = getResultItemType(elemName); 492e5c31af7Sopenharmony_ci ri::Item* item = DE_NULL; 493e5c31af7Sopenharmony_ci ri::Item* parentItem = getCurrentItem(); 494e5c31af7Sopenharmony_ci ri::Type parentType = parentItem ? parentItem->getType() : ri::TYPE_LAST; 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ci switch (itemType) 497e5c31af7Sopenharmony_ci { 498e5c31af7Sopenharmony_ci case ri::TYPE_RESULT: 499e5c31af7Sopenharmony_ci { 500e5c31af7Sopenharmony_ci ri::Result* result = curList->allocItem<ri::Result>(); 501e5c31af7Sopenharmony_ci result->statusCode = getTestStatusCode(getAttribute("StatusCode")); 502e5c31af7Sopenharmony_ci item = result; 503e5c31af7Sopenharmony_ci break; 504e5c31af7Sopenharmony_ci } 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci case ri::TYPE_TEXT: 507e5c31af7Sopenharmony_ci item = curList->allocItem<ri::Text>(); 508e5c31af7Sopenharmony_ci break; 509e5c31af7Sopenharmony_ci 510e5c31af7Sopenharmony_ci case ri::TYPE_SECTION: 511e5c31af7Sopenharmony_ci { 512e5c31af7Sopenharmony_ci ri::Section* section = curList->allocItem<ri::Section>(); 513e5c31af7Sopenharmony_ci section->name = getAttribute("Name"); 514e5c31af7Sopenharmony_ci section->description = getAttribute("Description"); 515e5c31af7Sopenharmony_ci item = section; 516e5c31af7Sopenharmony_ci break; 517e5c31af7Sopenharmony_ci } 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci case ri::TYPE_NUMBER: 520e5c31af7Sopenharmony_ci { 521e5c31af7Sopenharmony_ci ri::Number* number = curList->allocItem<ri::Number>(); 522e5c31af7Sopenharmony_ci number->name = getAttribute("Name"); 523e5c31af7Sopenharmony_ci number->description = getAttribute("Description"); 524e5c31af7Sopenharmony_ci number->unit = getAttribute("Unit"); 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci if (m_xmlParser.hasAttribute("Tag")) 527e5c31af7Sopenharmony_ci number->tag = m_xmlParser.getAttribute("Tag"); 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci item = number; 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci m_curNumValue.clear(); 532e5c31af7Sopenharmony_ci break; 533e5c31af7Sopenharmony_ci } 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci case ri::TYPE_IMAGESET: 536e5c31af7Sopenharmony_ci { 537e5c31af7Sopenharmony_ci ri::ImageSet* imageSet = curList->allocItem<ri::ImageSet>(); 538e5c31af7Sopenharmony_ci imageSet->name = getAttribute("Name"); 539e5c31af7Sopenharmony_ci imageSet->description = getAttribute("Description"); 540e5c31af7Sopenharmony_ci item = imageSet; 541e5c31af7Sopenharmony_ci break; 542e5c31af7Sopenharmony_ci } 543e5c31af7Sopenharmony_ci 544e5c31af7Sopenharmony_ci case ri::TYPE_IMAGE: 545e5c31af7Sopenharmony_ci { 546e5c31af7Sopenharmony_ci ri::Image* image = curList->allocItem<ri::Image>(); 547e5c31af7Sopenharmony_ci image->name = getAttribute("Name"); 548e5c31af7Sopenharmony_ci image->description = getAttribute("Description"); 549e5c31af7Sopenharmony_ci image->width = toInt(getAttribute("Width")); 550e5c31af7Sopenharmony_ci image->height = toInt(getAttribute("Height")); 551e5c31af7Sopenharmony_ci image->format = getImageFormat(getAttribute("Format")); 552e5c31af7Sopenharmony_ci image->compression = getImageCompression(getAttribute("CompressionMode")); 553e5c31af7Sopenharmony_ci item = image; 554e5c31af7Sopenharmony_ci break; 555e5c31af7Sopenharmony_ci } 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci case ri::TYPE_SHADERPROGRAM: 558e5c31af7Sopenharmony_ci { 559e5c31af7Sopenharmony_ci ri::ShaderProgram* shaderProgram = curList->allocItem<ri::ShaderProgram>(); 560e5c31af7Sopenharmony_ci shaderProgram->linkStatus = toBool(getAttribute("LinkStatus")); 561e5c31af7Sopenharmony_ci item = shaderProgram; 562e5c31af7Sopenharmony_ci break; 563e5c31af7Sopenharmony_ci } 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ci case ri::TYPE_SHADER: 566e5c31af7Sopenharmony_ci { 567e5c31af7Sopenharmony_ci if (parentType != ri::TYPE_SHADERPROGRAM) 568e5c31af7Sopenharmony_ci throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>"); 569e5c31af7Sopenharmony_ci 570e5c31af7Sopenharmony_ci ri::Shader* shader = curList->allocItem<ri::Shader>(); 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ci shader->shaderType = getShaderTypeFromTagName(elemName); 573e5c31af7Sopenharmony_ci shader->compileStatus = toBool(getAttribute("CompileStatus")); 574e5c31af7Sopenharmony_ci 575e5c31af7Sopenharmony_ci item = shader; 576e5c31af7Sopenharmony_ci break; 577e5c31af7Sopenharmony_ci } 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ci case ri::TYPE_SPIRVSOURCE: 580e5c31af7Sopenharmony_ci { 581e5c31af7Sopenharmony_ci if (parentType != ri::TYPE_SHADERPROGRAM) 582e5c31af7Sopenharmony_ci throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>"); 583e5c31af7Sopenharmony_ci item = curList->allocItem<ri::SpirVSource>(); 584e5c31af7Sopenharmony_ci break; 585e5c31af7Sopenharmony_ci } 586e5c31af7Sopenharmony_ci 587e5c31af7Sopenharmony_ci case ri::TYPE_SHADERSOURCE: 588e5c31af7Sopenharmony_ci if (parentType == ri::TYPE_SHADER) 589e5c31af7Sopenharmony_ci item = &static_cast<ri::Shader*>(parentItem)->source; 590e5c31af7Sopenharmony_ci else 591e5c31af7Sopenharmony_ci throw TestResultParseError("Unexpected <ShaderSource>"); 592e5c31af7Sopenharmony_ci break; 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_ci case ri::TYPE_INFOLOG: 595e5c31af7Sopenharmony_ci if (parentType == ri::TYPE_SHADERPROGRAM) 596e5c31af7Sopenharmony_ci item = &static_cast<ri::ShaderProgram*>(parentItem)->linkInfoLog; 597e5c31af7Sopenharmony_ci else if (parentType == ri::TYPE_SHADER) 598e5c31af7Sopenharmony_ci item = &static_cast<ri::Shader*>(parentItem)->infoLog; 599e5c31af7Sopenharmony_ci else if (parentType == ri::TYPE_COMPILEINFO) 600e5c31af7Sopenharmony_ci item = &static_cast<ri::CompileInfo*>(parentItem)->infoLog; 601e5c31af7Sopenharmony_ci else 602e5c31af7Sopenharmony_ci throw TestResultParseError("Unexpected <InfoLog>"); 603e5c31af7Sopenharmony_ci break; 604e5c31af7Sopenharmony_ci 605e5c31af7Sopenharmony_ci case ri::TYPE_KERNELSOURCE: 606e5c31af7Sopenharmony_ci item = curList->allocItem<ri::KernelSource>(); 607e5c31af7Sopenharmony_ci break; 608e5c31af7Sopenharmony_ci 609e5c31af7Sopenharmony_ci case ri::TYPE_COMPILEINFO: 610e5c31af7Sopenharmony_ci { 611e5c31af7Sopenharmony_ci ri::CompileInfo* info = curList->allocItem<ri::CompileInfo>(); 612e5c31af7Sopenharmony_ci info->name = getAttribute("Name"); 613e5c31af7Sopenharmony_ci info->description = getAttribute("Description"); 614e5c31af7Sopenharmony_ci info->compileStatus = toBool(getAttribute("CompileStatus")); 615e5c31af7Sopenharmony_ci item = info; 616e5c31af7Sopenharmony_ci break; 617e5c31af7Sopenharmony_ci } 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_ci case ri::TYPE_EGLCONFIGSET: 620e5c31af7Sopenharmony_ci { 621e5c31af7Sopenharmony_ci ri::EglConfigSet* set = curList->allocItem<ri::EglConfigSet>(); 622e5c31af7Sopenharmony_ci set->name = getAttribute("Name"); 623e5c31af7Sopenharmony_ci set->description = m_xmlParser.hasAttribute("Description") ? m_xmlParser.getAttribute("Description") : ""; 624e5c31af7Sopenharmony_ci item = set; 625e5c31af7Sopenharmony_ci break; 626e5c31af7Sopenharmony_ci } 627e5c31af7Sopenharmony_ci 628e5c31af7Sopenharmony_ci case ri::TYPE_EGLCONFIG: 629e5c31af7Sopenharmony_ci { 630e5c31af7Sopenharmony_ci ri::EglConfig* config = curList->allocItem<ri::EglConfig>(); 631e5c31af7Sopenharmony_ci config->bufferSize = toInt(getAttribute("BufferSize")); 632e5c31af7Sopenharmony_ci config->redSize = toInt(getAttribute("RedSize")); 633e5c31af7Sopenharmony_ci config->greenSize = toInt(getAttribute("GreenSize")); 634e5c31af7Sopenharmony_ci config->blueSize = toInt(getAttribute("BlueSize")); 635e5c31af7Sopenharmony_ci config->luminanceSize = toInt(getAttribute("LuminanceSize")); 636e5c31af7Sopenharmony_ci config->alphaSize = toInt(getAttribute("AlphaSize")); 637e5c31af7Sopenharmony_ci config->alphaMaskSize = toInt(getAttribute("AlphaMaskSize")); 638e5c31af7Sopenharmony_ci config->bindToTextureRGB = toBool(getAttribute("BindToTextureRGB")); 639e5c31af7Sopenharmony_ci config->bindToTextureRGBA = toBool(getAttribute("BindToTextureRGBA")); 640e5c31af7Sopenharmony_ci config->colorBufferType = getAttribute("ColorBufferType"); 641e5c31af7Sopenharmony_ci config->configCaveat = getAttribute("ConfigCaveat"); 642e5c31af7Sopenharmony_ci config->configID = toInt(getAttribute("ConfigID")); 643e5c31af7Sopenharmony_ci config->conformant = getAttribute("Conformant"); 644e5c31af7Sopenharmony_ci config->depthSize = toInt(getAttribute("DepthSize")); 645e5c31af7Sopenharmony_ci config->level = toInt(getAttribute("Level")); 646e5c31af7Sopenharmony_ci config->maxPBufferWidth = toInt(getAttribute("MaxPBufferWidth")); 647e5c31af7Sopenharmony_ci config->maxPBufferHeight = toInt(getAttribute("MaxPBufferHeight")); 648e5c31af7Sopenharmony_ci config->maxPBufferPixels = toInt(getAttribute("MaxPBufferPixels")); 649e5c31af7Sopenharmony_ci config->maxSwapInterval = toInt(getAttribute("MaxSwapInterval")); 650e5c31af7Sopenharmony_ci config->minSwapInterval = toInt(getAttribute("MinSwapInterval")); 651e5c31af7Sopenharmony_ci config->nativeRenderable = toBool(getAttribute("NativeRenderable")); 652e5c31af7Sopenharmony_ci config->renderableType = getAttribute("RenderableType"); 653e5c31af7Sopenharmony_ci config->sampleBuffers = toInt(getAttribute("SampleBuffers")); 654e5c31af7Sopenharmony_ci config->samples = toInt(getAttribute("Samples")); 655e5c31af7Sopenharmony_ci config->stencilSize = toInt(getAttribute("StencilSize")); 656e5c31af7Sopenharmony_ci config->surfaceTypes = getAttribute("SurfaceTypes"); 657e5c31af7Sopenharmony_ci config->transparentType = getAttribute("TransparentType"); 658e5c31af7Sopenharmony_ci config->transparentRedValue = toInt(getAttribute("TransparentRedValue")); 659e5c31af7Sopenharmony_ci config->transparentGreenValue = toInt(getAttribute("TransparentGreenValue")); 660e5c31af7Sopenharmony_ci config->transparentBlueValue = toInt(getAttribute("TransparentBlueValue")); 661e5c31af7Sopenharmony_ci item = config; 662e5c31af7Sopenharmony_ci break; 663e5c31af7Sopenharmony_ci } 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLELIST: 666e5c31af7Sopenharmony_ci { 667e5c31af7Sopenharmony_ci ri::SampleList* list = curList->allocItem<ri::SampleList>(); 668e5c31af7Sopenharmony_ci list->name = getAttribute("Name"); 669e5c31af7Sopenharmony_ci list->description = getAttribute("Description"); 670e5c31af7Sopenharmony_ci item = list; 671e5c31af7Sopenharmony_ci break; 672e5c31af7Sopenharmony_ci } 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLEINFO: 675e5c31af7Sopenharmony_ci { 676e5c31af7Sopenharmony_ci if (parentType != ri::TYPE_SAMPLELIST) 677e5c31af7Sopenharmony_ci throw TestResultParseError("<SampleInfo> outside of <SampleList>"); 678e5c31af7Sopenharmony_ci 679e5c31af7Sopenharmony_ci ri::SampleList* list = static_cast<ri::SampleList*>(parentItem); 680e5c31af7Sopenharmony_ci ri::SampleInfo* info = &list->sampleInfo; 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci item = info; 683e5c31af7Sopenharmony_ci break; 684e5c31af7Sopenharmony_ci } 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci case ri::TYPE_VALUEINFO: 687e5c31af7Sopenharmony_ci { 688e5c31af7Sopenharmony_ci if (parentType != ri::TYPE_SAMPLEINFO) 689e5c31af7Sopenharmony_ci throw TestResultParseError("<ValueInfo> outside of <SampleInfo>"); 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci ri::SampleInfo* sampleInfo = static_cast<ri::SampleInfo*>(parentItem); 692e5c31af7Sopenharmony_ci ri::ValueInfo* valueInfo = sampleInfo->valueInfos.allocItem<ri::ValueInfo>(); 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_ci valueInfo->name = getAttribute("Name"); 695e5c31af7Sopenharmony_ci valueInfo->description = getAttribute("Description"); 696e5c31af7Sopenharmony_ci valueInfo->tag = getSampleValueTag(getAttribute("Tag")); 697e5c31af7Sopenharmony_ci 698e5c31af7Sopenharmony_ci if (m_xmlParser.hasAttribute("Unit")) 699e5c31af7Sopenharmony_ci valueInfo->unit = getAttribute("Unit"); 700e5c31af7Sopenharmony_ci 701e5c31af7Sopenharmony_ci item = valueInfo; 702e5c31af7Sopenharmony_ci break; 703e5c31af7Sopenharmony_ci } 704e5c31af7Sopenharmony_ci 705e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLE: 706e5c31af7Sopenharmony_ci { 707e5c31af7Sopenharmony_ci if (parentType != ri::TYPE_SAMPLELIST) 708e5c31af7Sopenharmony_ci throw TestResultParseError("<Sample> outside of <SampleList>"); 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci ri::SampleList* list = static_cast<ri::SampleList*>(parentItem); 711e5c31af7Sopenharmony_ci ri::Sample* sample = list->samples.allocItem<ri::Sample>(); 712e5c31af7Sopenharmony_ci 713e5c31af7Sopenharmony_ci item = sample; 714e5c31af7Sopenharmony_ci break; 715e5c31af7Sopenharmony_ci } 716e5c31af7Sopenharmony_ci 717e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLEVALUE: 718e5c31af7Sopenharmony_ci { 719e5c31af7Sopenharmony_ci if (parentType != ri::TYPE_SAMPLE) 720e5c31af7Sopenharmony_ci throw TestResultParseError("<Value> outside of <Sample>"); 721e5c31af7Sopenharmony_ci 722e5c31af7Sopenharmony_ci ri::Sample* sample = static_cast<ri::Sample*>(parentItem); 723e5c31af7Sopenharmony_ci ri::SampleValue* value = sample->values.allocItem<ri::SampleValue>(); 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_ci item = value; 726e5c31af7Sopenharmony_ci break; 727e5c31af7Sopenharmony_ci } 728e5c31af7Sopenharmony_ci 729e5c31af7Sopenharmony_ci default: 730e5c31af7Sopenharmony_ci throw TestResultParseError(string("Unsupported element '") + elemName + ("'")); 731e5c31af7Sopenharmony_ci } 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ci DE_ASSERT(item); 734e5c31af7Sopenharmony_ci pushItem(item); 735e5c31af7Sopenharmony_ci 736e5c31af7Sopenharmony_ci // Reset base64 decoding offset. 737e5c31af7Sopenharmony_ci m_base64DecodeOffset = 0; 738e5c31af7Sopenharmony_ci } 739e5c31af7Sopenharmony_ci} 740e5c31af7Sopenharmony_ci 741e5c31af7Sopenharmony_civoid TestResultParser::handleElementEnd (void) 742e5c31af7Sopenharmony_ci{ 743e5c31af7Sopenharmony_ci const char* elemName = m_xmlParser.getElementName(); 744e5c31af7Sopenharmony_ci 745e5c31af7Sopenharmony_ci if (m_state != STATE_IN_TEST_CASE_RESULT) 746e5c31af7Sopenharmony_ci throw TestResultParseError(string("Unexpected </") + elemName + "> outside of <TestCaseResult>"); 747e5c31af7Sopenharmony_ci 748e5c31af7Sopenharmony_ci if (deStringEqual(elemName, "TestCaseResult")) 749e5c31af7Sopenharmony_ci { 750e5c31af7Sopenharmony_ci // Logs from buggy test cases may contain invalid XML. 751e5c31af7Sopenharmony_ci // DE_ASSERT(getCurrentItem() == DE_NULL); 752e5c31af7Sopenharmony_ci // \todo [2012-11-22 pyry] Log warning. 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ci m_state = STATE_TEST_CASE_RESULT_ENDED; 755e5c31af7Sopenharmony_ci } 756e5c31af7Sopenharmony_ci else 757e5c31af7Sopenharmony_ci { 758e5c31af7Sopenharmony_ci ri::Type itemType = getResultItemType(elemName); 759e5c31af7Sopenharmony_ci ri::Item* curItem = getCurrentItem(); 760e5c31af7Sopenharmony_ci 761e5c31af7Sopenharmony_ci if (!curItem || itemType != curItem->getType()) 762e5c31af7Sopenharmony_ci throw TestResultParseError(string("Unexpected </") + elemName + ">"); 763e5c31af7Sopenharmony_ci 764e5c31af7Sopenharmony_ci if (itemType == ri::TYPE_RESULT) 765e5c31af7Sopenharmony_ci { 766e5c31af7Sopenharmony_ci ri::Result* result = static_cast<ri::Result*>(curItem); 767e5c31af7Sopenharmony_ci m_result->statusCode = result->statusCode; 768e5c31af7Sopenharmony_ci m_result->statusDetails = result->details; 769e5c31af7Sopenharmony_ci } 770e5c31af7Sopenharmony_ci else if (itemType == ri::TYPE_NUMBER) 771e5c31af7Sopenharmony_ci { 772e5c31af7Sopenharmony_ci // Parse value for number. 773e5c31af7Sopenharmony_ci ri::Number* number = static_cast<ri::Number*>(curItem); 774e5c31af7Sopenharmony_ci number->value = getNumericValue(m_curNumValue); 775e5c31af7Sopenharmony_ci m_curNumValue.clear(); 776e5c31af7Sopenharmony_ci } 777e5c31af7Sopenharmony_ci else if (itemType == ri::TYPE_SAMPLEVALUE) 778e5c31af7Sopenharmony_ci { 779e5c31af7Sopenharmony_ci ri::SampleValue* value = static_cast<ri::SampleValue*>(curItem); 780e5c31af7Sopenharmony_ci value->value = getNumericValue(m_curNumValue); 781e5c31af7Sopenharmony_ci m_curNumValue.clear(); 782e5c31af7Sopenharmony_ci } 783e5c31af7Sopenharmony_ci 784e5c31af7Sopenharmony_ci popItem(); 785e5c31af7Sopenharmony_ci } 786e5c31af7Sopenharmony_ci} 787e5c31af7Sopenharmony_ci 788e5c31af7Sopenharmony_civoid TestResultParser::handleData (void) 789e5c31af7Sopenharmony_ci{ 790e5c31af7Sopenharmony_ci ri::Item* curItem = getCurrentItem(); 791e5c31af7Sopenharmony_ci ri::Type type = curItem ? curItem->getType() : ri::TYPE_LAST; 792e5c31af7Sopenharmony_ci 793e5c31af7Sopenharmony_ci switch (type) 794e5c31af7Sopenharmony_ci { 795e5c31af7Sopenharmony_ci case ri::TYPE_RESULT: 796e5c31af7Sopenharmony_ci m_xmlParser.appendDataStr(static_cast<ri::Result*>(curItem)->details); 797e5c31af7Sopenharmony_ci break; 798e5c31af7Sopenharmony_ci 799e5c31af7Sopenharmony_ci case ri::TYPE_TEXT: 800e5c31af7Sopenharmony_ci m_xmlParser.appendDataStr(static_cast<ri::Text*>(curItem)->text); 801e5c31af7Sopenharmony_ci break; 802e5c31af7Sopenharmony_ci 803e5c31af7Sopenharmony_ci case ri::TYPE_SHADERSOURCE: 804e5c31af7Sopenharmony_ci m_xmlParser.appendDataStr(static_cast<ri::ShaderSource*>(curItem)->source); 805e5c31af7Sopenharmony_ci break; 806e5c31af7Sopenharmony_ci 807e5c31af7Sopenharmony_ci case ri::TYPE_SPIRVSOURCE: 808e5c31af7Sopenharmony_ci m_xmlParser.appendDataStr(static_cast<ri::SpirVSource*>(curItem)->source); 809e5c31af7Sopenharmony_ci break; 810e5c31af7Sopenharmony_ci 811e5c31af7Sopenharmony_ci case ri::TYPE_INFOLOG: 812e5c31af7Sopenharmony_ci m_xmlParser.appendDataStr(static_cast<ri::InfoLog*>(curItem)->log); 813e5c31af7Sopenharmony_ci break; 814e5c31af7Sopenharmony_ci 815e5c31af7Sopenharmony_ci case ri::TYPE_KERNELSOURCE: 816e5c31af7Sopenharmony_ci m_xmlParser.appendDataStr(static_cast<ri::KernelSource*>(curItem)->source); 817e5c31af7Sopenharmony_ci break; 818e5c31af7Sopenharmony_ci 819e5c31af7Sopenharmony_ci case ri::TYPE_NUMBER: 820e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLEVALUE: 821e5c31af7Sopenharmony_ci m_xmlParser.appendDataStr(m_curNumValue); 822e5c31af7Sopenharmony_ci break; 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci case ri::TYPE_IMAGE: 825e5c31af7Sopenharmony_ci { 826e5c31af7Sopenharmony_ci ri::Image* image = static_cast<ri::Image*>(curItem); 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci // Base64 decode. 829e5c31af7Sopenharmony_ci int numBytesIn = m_xmlParser.getDataSize(); 830e5c31af7Sopenharmony_ci 831e5c31af7Sopenharmony_ci for (int inNdx = 0; inNdx < numBytesIn; inNdx++) 832e5c31af7Sopenharmony_ci { 833e5c31af7Sopenharmony_ci deUint8 byte = m_xmlParser.getDataByte(inNdx); 834e5c31af7Sopenharmony_ci deUint8 decodedBits = 0; 835e5c31af7Sopenharmony_ci 836e5c31af7Sopenharmony_ci if (de::inRange<deInt8>(byte, 'A', 'Z')) 837e5c31af7Sopenharmony_ci decodedBits = (deUint8)(byte - 'A'); 838e5c31af7Sopenharmony_ci else if (de::inRange<deInt8>(byte, 'a', 'z')) 839e5c31af7Sopenharmony_ci decodedBits = (deUint8)(('Z'-'A'+1) + (byte-'a')); 840e5c31af7Sopenharmony_ci else if (de::inRange<deInt8>(byte, '0', '9')) 841e5c31af7Sopenharmony_ci decodedBits = (deUint8)(('Z'-'A'+1) + ('z'-'a'+1) + (byte-'0')); 842e5c31af7Sopenharmony_ci else if (byte == '+') 843e5c31af7Sopenharmony_ci decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+1); 844e5c31af7Sopenharmony_ci else if (byte == '/') 845e5c31af7Sopenharmony_ci decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+2); 846e5c31af7Sopenharmony_ci else if (byte == '=') 847e5c31af7Sopenharmony_ci { 848e5c31af7Sopenharmony_ci // Padding at end - remove last byte. 849e5c31af7Sopenharmony_ci if (image->data.empty()) 850e5c31af7Sopenharmony_ci throw TestResultParseError("Malformed base64 data"); 851e5c31af7Sopenharmony_ci image->data.pop_back(); 852e5c31af7Sopenharmony_ci continue; 853e5c31af7Sopenharmony_ci } 854e5c31af7Sopenharmony_ci else 855e5c31af7Sopenharmony_ci continue; // Not an B64 input character. 856e5c31af7Sopenharmony_ci 857e5c31af7Sopenharmony_ci int phase = m_base64DecodeOffset % 4; 858e5c31af7Sopenharmony_ci 859e5c31af7Sopenharmony_ci if (phase == 0) 860e5c31af7Sopenharmony_ci image->data.resize(image->data.size()+3, 0); 861e5c31af7Sopenharmony_ci 862e5c31af7Sopenharmony_ci if ((int)image->data.size() < (m_base64DecodeOffset>>2)*3 + 3) 863e5c31af7Sopenharmony_ci throw TestResultParseError("Malformed base64 data"); 864e5c31af7Sopenharmony_ci deUint8* outPtr = &image->data[(m_base64DecodeOffset>>2)*3]; 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci switch (phase) 867e5c31af7Sopenharmony_ci { 868e5c31af7Sopenharmony_ci case 0: outPtr[0] |= (deUint8)(decodedBits<<2); break; 869e5c31af7Sopenharmony_ci case 1: outPtr[0] = (deUint8)(outPtr[0] | (deUint8)(decodedBits>>4)); outPtr[1] = (deUint8)(outPtr[1] | (deUint8)((decodedBits&0xF)<<4)); break; 870e5c31af7Sopenharmony_ci case 2: outPtr[1] = (deUint8)(outPtr[1] | (deUint8)(decodedBits>>2)); outPtr[2] = (deUint8)(outPtr[2] | (deUint8)((decodedBits&0x3)<<6)); break; 871e5c31af7Sopenharmony_ci case 3: outPtr[2] |= decodedBits; break; 872e5c31af7Sopenharmony_ci default: 873e5c31af7Sopenharmony_ci DE_ASSERT(false); 874e5c31af7Sopenharmony_ci } 875e5c31af7Sopenharmony_ci 876e5c31af7Sopenharmony_ci m_base64DecodeOffset += 1; 877e5c31af7Sopenharmony_ci } 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci break; 880e5c31af7Sopenharmony_ci } 881e5c31af7Sopenharmony_ci 882e5c31af7Sopenharmony_ci default: 883e5c31af7Sopenharmony_ci // Just ignore data. 884e5c31af7Sopenharmony_ci break; 885e5c31af7Sopenharmony_ci } 886e5c31af7Sopenharmony_ci} 887e5c31af7Sopenharmony_ci 888e5c31af7Sopenharmony_ci//! Helper for parsing TestCaseResult from TestCaseResultData. 889e5c31af7Sopenharmony_civoid parseTestCaseResultFromData (TestResultParser* parser, TestCaseResult* result, const TestCaseResultData& data) 890e5c31af7Sopenharmony_ci{ 891e5c31af7Sopenharmony_ci DE_ASSERT(result->resultItems.getNumItems() == 0); 892e5c31af7Sopenharmony_ci 893e5c31af7Sopenharmony_ci // Initialize status codes etc. from data. 894e5c31af7Sopenharmony_ci result->casePath = data.getTestCasePath(); 895e5c31af7Sopenharmony_ci result->caseType = TESTCASETYPE_SELF_VALIDATE; 896e5c31af7Sopenharmony_ci result->statusCode = data.getStatusCode(); 897e5c31af7Sopenharmony_ci result->statusDetails = data.getStatusDetails(); 898e5c31af7Sopenharmony_ci 899e5c31af7Sopenharmony_ci if (data.getDataSize() > 0) 900e5c31af7Sopenharmony_ci { 901e5c31af7Sopenharmony_ci parser->init(result); 902e5c31af7Sopenharmony_ci 903e5c31af7Sopenharmony_ci const TestResultParser::ParseResult parseResult = parser->parse(data.getData(), data.getDataSize()); 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ci if (result->statusCode == TESTSTATUSCODE_LAST) 906e5c31af7Sopenharmony_ci { 907e5c31af7Sopenharmony_ci result->statusCode = TESTSTATUSCODE_INTERNAL_ERROR; 908e5c31af7Sopenharmony_ci 909e5c31af7Sopenharmony_ci if (parseResult == TestResultParser::PARSERESULT_ERROR) 910e5c31af7Sopenharmony_ci result->statusDetails = "Test case result parsing failed"; 911e5c31af7Sopenharmony_ci else if (parseResult != TestResultParser::PARSERESULT_COMPLETE) 912e5c31af7Sopenharmony_ci result->statusDetails = "Incomplete test case result"; 913e5c31af7Sopenharmony_ci else 914e5c31af7Sopenharmony_ci result->statusDetails = "Test case result is missing <Result> item"; 915e5c31af7Sopenharmony_ci } 916e5c31af7Sopenharmony_ci } 917e5c31af7Sopenharmony_ci else if (result->statusCode == TESTSTATUSCODE_LAST) 918e5c31af7Sopenharmony_ci { 919e5c31af7Sopenharmony_ci result->statusCode = TESTSTATUSCODE_TERMINATED; 920e5c31af7Sopenharmony_ci result->statusDetails = "Empty test case result"; 921e5c31af7Sopenharmony_ci } 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci if (result->casePath.empty()) 924e5c31af7Sopenharmony_ci throw Error("Empty test case path in result"); 925e5c31af7Sopenharmony_ci 926e5c31af7Sopenharmony_ci if (result->caseType == TESTCASETYPE_LAST) 927e5c31af7Sopenharmony_ci throw Error("Invalid test case type in result"); 928e5c31af7Sopenharmony_ci 929e5c31af7Sopenharmony_ci DE_ASSERT(result->statusCode != TESTSTATUSCODE_LAST); 930e5c31af7Sopenharmony_ci} 931e5c31af7Sopenharmony_ci 932e5c31af7Sopenharmony_ci} // xe 933