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 log writer. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "xeTestLogWriter.hpp" 25e5c31af7Sopenharmony_ci#include "xeXMLWriter.hpp" 26e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 27e5c31af7Sopenharmony_ci 28e5c31af7Sopenharmony_ci#include <fstream> 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_cinamespace xe 31e5c31af7Sopenharmony_ci{ 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ci/* Batch result writer. */ 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_cistruct ContainerValue 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_ci ContainerValue (const std::string& value_) : value(value_) {} 38e5c31af7Sopenharmony_ci ContainerValue (const char* value_) : value(value_) {} 39e5c31af7Sopenharmony_ci std::string value; 40e5c31af7Sopenharmony_ci}; 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& stream, const ContainerValue& value) 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_ci if (value.value.find(' ') != std::string::npos) 45e5c31af7Sopenharmony_ci { 46e5c31af7Sopenharmony_ci // Escape. 47e5c31af7Sopenharmony_ci stream << '"'; 48e5c31af7Sopenharmony_ci for (std::string::const_iterator i = value.value.begin(); i != value.value.end(); i++) 49e5c31af7Sopenharmony_ci { 50e5c31af7Sopenharmony_ci if (*i == '"' || *i == '\\') 51e5c31af7Sopenharmony_ci stream << '\\'; 52e5c31af7Sopenharmony_ci stream << *i; 53e5c31af7Sopenharmony_ci } 54e5c31af7Sopenharmony_ci stream << '"'; 55e5c31af7Sopenharmony_ci } 56e5c31af7Sopenharmony_ci else 57e5c31af7Sopenharmony_ci stream << value.value; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ci return stream; 60e5c31af7Sopenharmony_ci} 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_cistatic void writeSessionInfo (const SessionInfo& info, std::ostream& stream) 63e5c31af7Sopenharmony_ci{ 64e5c31af7Sopenharmony_ci if (!info.releaseName.empty()) 65e5c31af7Sopenharmony_ci stream << "#sessionInfo releaseName " << ContainerValue(info.releaseName) << "\n"; 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ci if (!info.releaseId.empty()) 68e5c31af7Sopenharmony_ci stream << "#sessionInfo releaseId " << ContainerValue(info.releaseId) << "\n"; 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci if (!info.targetName.empty()) 71e5c31af7Sopenharmony_ci stream << "#sessionInfo targetName " << ContainerValue(info.targetName) << "\n"; 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ci if (!info.candyTargetName.empty()) 74e5c31af7Sopenharmony_ci stream << "#sessionInfo candyTargetName " << ContainerValue(info.candyTargetName) << "\n"; 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ci if (!info.configName.empty()) 77e5c31af7Sopenharmony_ci stream << "#sessionInfo configName " << ContainerValue(info.configName) << "\n"; 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci if (!info.resultName.empty()) 80e5c31af7Sopenharmony_ci stream << "#sessionInfo resultName " << ContainerValue(info.resultName) << "\n"; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci // \note Current format uses unescaped timestamps for some strange reason. 83e5c31af7Sopenharmony_ci if (!info.timestamp.empty()) 84e5c31af7Sopenharmony_ci stream << "#sessionInfo timestamp " << info.timestamp << "\n"; 85e5c31af7Sopenharmony_ci} 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_cistatic void writeTestCase (const TestCaseResultData& caseData, std::ostream& stream) 88e5c31af7Sopenharmony_ci{ 89e5c31af7Sopenharmony_ci stream << "\n#beginTestCaseResult " << caseData.getTestCasePath() << "\n"; 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci if (caseData.getDataSize() > 0) 92e5c31af7Sopenharmony_ci { 93e5c31af7Sopenharmony_ci stream.write((const char*)caseData.getData(), caseData.getDataSize()); 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci deUint8 lastCh = caseData.getData()[caseData.getDataSize()-1]; 96e5c31af7Sopenharmony_ci if (lastCh != '\n' && lastCh != '\r') 97e5c31af7Sopenharmony_ci stream << "\n"; 98e5c31af7Sopenharmony_ci } 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci TestStatusCode dataCode = caseData.getStatusCode(); 101e5c31af7Sopenharmony_ci if (dataCode == TESTSTATUSCODE_CRASH || 102e5c31af7Sopenharmony_ci dataCode == TESTSTATUSCODE_TIMEOUT || 103e5c31af7Sopenharmony_ci dataCode == TESTSTATUSCODE_TERMINATED) 104e5c31af7Sopenharmony_ci stream << "#terminateTestCaseResult " << getTestStatusCodeName(dataCode) << "\n"; 105e5c31af7Sopenharmony_ci else 106e5c31af7Sopenharmony_ci stream << "#endTestCaseResult\n"; 107e5c31af7Sopenharmony_ci} 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_civoid writeTestLog (const BatchResult& result, std::ostream& stream) 110e5c31af7Sopenharmony_ci{ 111e5c31af7Sopenharmony_ci writeSessionInfo(result.getSessionInfo(), stream); 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci stream << "#beginSession\n"; 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < result.getNumTestCaseResults(); ndx++) 116e5c31af7Sopenharmony_ci { 117e5c31af7Sopenharmony_ci ConstTestCaseResultPtr caseData = result.getTestCaseResult(ndx); 118e5c31af7Sopenharmony_ci writeTestCase(*caseData, stream); 119e5c31af7Sopenharmony_ci } 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci stream << "\n#endSession\n"; 122e5c31af7Sopenharmony_ci} 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_civoid writeBatchResultToFile (const BatchResult& result, const char* filename) 125e5c31af7Sopenharmony_ci{ 126e5c31af7Sopenharmony_ci std::ofstream str(filename, std::ofstream::binary|std::ofstream::trunc); 127e5c31af7Sopenharmony_ci writeTestLog(result, str); 128e5c31af7Sopenharmony_ci str.close(); 129e5c31af7Sopenharmony_ci} 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci/* Test result log writer. */ 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_cistatic const char* getImageFormatName (ri::Image::Format format) 134e5c31af7Sopenharmony_ci{ 135e5c31af7Sopenharmony_ci switch (format) 136e5c31af7Sopenharmony_ci { 137e5c31af7Sopenharmony_ci case ri::Image::FORMAT_RGB888: return "RGB888"; 138e5c31af7Sopenharmony_ci case ri::Image::FORMAT_RGBA8888: return "RGBA8888"; 139e5c31af7Sopenharmony_ci default: 140e5c31af7Sopenharmony_ci DE_ASSERT(false); 141e5c31af7Sopenharmony_ci return DE_NULL; 142e5c31af7Sopenharmony_ci } 143e5c31af7Sopenharmony_ci} 144e5c31af7Sopenharmony_ci 145e5c31af7Sopenharmony_cistatic const char* getImageCompressionName (ri::Image::Compression compression) 146e5c31af7Sopenharmony_ci{ 147e5c31af7Sopenharmony_ci switch (compression) 148e5c31af7Sopenharmony_ci { 149e5c31af7Sopenharmony_ci case ri::Image::COMPRESSION_NONE: return "None"; 150e5c31af7Sopenharmony_ci case ri::Image::COMPRESSION_PNG: return "PNG"; 151e5c31af7Sopenharmony_ci default: 152e5c31af7Sopenharmony_ci DE_ASSERT(false); 153e5c31af7Sopenharmony_ci return DE_NULL; 154e5c31af7Sopenharmony_ci } 155e5c31af7Sopenharmony_ci} 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_cistatic const char* getSampleValueTagName (ri::ValueInfo::ValueTag tag) 158e5c31af7Sopenharmony_ci{ 159e5c31af7Sopenharmony_ci switch (tag) 160e5c31af7Sopenharmony_ci { 161e5c31af7Sopenharmony_ci case ri::ValueInfo::VALUETAG_PREDICTOR: return "Predictor"; 162e5c31af7Sopenharmony_ci case ri::ValueInfo::VALUETAG_RESPONSE: return "Response"; 163e5c31af7Sopenharmony_ci default: 164e5c31af7Sopenharmony_ci DE_ASSERT(false); 165e5c31af7Sopenharmony_ci return DE_NULL; 166e5c31af7Sopenharmony_ci } 167e5c31af7Sopenharmony_ci} 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ciinline const char* getBoolName (bool val) 170e5c31af7Sopenharmony_ci{ 171e5c31af7Sopenharmony_ci return val ? "True" : "False"; 172e5c31af7Sopenharmony_ci} 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci// \todo [2012-09-07 pyry] Move to tcutil? 175e5c31af7Sopenharmony_ciclass Base64Formatter 176e5c31af7Sopenharmony_ci{ 177e5c31af7Sopenharmony_cipublic: 178e5c31af7Sopenharmony_ci const deUint8* data; 179e5c31af7Sopenharmony_ci int numBytes; 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci Base64Formatter (const deUint8* data_, int numBytes_) : data(data_), numBytes(numBytes_) {} 182e5c31af7Sopenharmony_ci}; 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, const Base64Formatter& fmt) 185e5c31af7Sopenharmony_ci{ 186e5c31af7Sopenharmony_ci static const char s_base64Table[64] = 187e5c31af7Sopenharmony_ci { 188e5c31af7Sopenharmony_ci 'A','B','C','D','E','F','G','H','I','J','K','L','M', 189e5c31af7Sopenharmony_ci 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 190e5c31af7Sopenharmony_ci 'a','b','c','d','e','f','g','h','i','j','k','l','m', 191e5c31af7Sopenharmony_ci 'n','o','p','q','r','s','t','u','v','w','x','y','z', 192e5c31af7Sopenharmony_ci '0','1','2','3','4','5','6','7','8','9','+','/' 193e5c31af7Sopenharmony_ci }; 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci const deUint8* data = fmt.data; 196e5c31af7Sopenharmony_ci int numBytes = fmt.numBytes; 197e5c31af7Sopenharmony_ci int srcNdx = 0; 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci DE_ASSERT(data && (numBytes > 0)); 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci /* Loop all input chars. */ 202e5c31af7Sopenharmony_ci while (srcNdx < numBytes) 203e5c31af7Sopenharmony_ci { 204e5c31af7Sopenharmony_ci int numRead = de::min(3, numBytes - srcNdx); 205e5c31af7Sopenharmony_ci deUint8 s0 = data[srcNdx]; 206e5c31af7Sopenharmony_ci deUint8 s1 = (numRead >= 2) ? data[srcNdx+1] : 0; 207e5c31af7Sopenharmony_ci deUint8 s2 = (numRead >= 3) ? data[srcNdx+2] : 0; 208e5c31af7Sopenharmony_ci char d[4]; 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ci srcNdx += numRead; 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci d[0] = s_base64Table[s0 >> 2]; 213e5c31af7Sopenharmony_ci d[1] = s_base64Table[((s0&0x3)<<4) | (s1>>4)]; 214e5c31af7Sopenharmony_ci d[2] = s_base64Table[((s1&0xF)<<2) | (s2>>6)]; 215e5c31af7Sopenharmony_ci d[3] = s_base64Table[s2&0x3F]; 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_ci if (numRead < 3) d[3] = '='; 218e5c31af7Sopenharmony_ci if (numRead < 2) d[2] = '='; 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_ci /* Write data. */ 221e5c31af7Sopenharmony_ci str.write(&d[0], sizeof(d)); 222e5c31af7Sopenharmony_ci } 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_ci return str; 225e5c31af7Sopenharmony_ci} 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ciinline Base64Formatter toBase64 (const deUint8* bytes, int numBytes) { return Base64Formatter(bytes, numBytes); } 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_cistatic const char* getStatusName (bool value) 230e5c31af7Sopenharmony_ci{ 231e5c31af7Sopenharmony_ci return value ? "OK" : "Fail"; 232e5c31af7Sopenharmony_ci} 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_cistatic void writeResultItem (const ri::Item& item, xml::Writer& dst) 235e5c31af7Sopenharmony_ci{ 236e5c31af7Sopenharmony_ci using xml::Writer; 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ci switch (item.getType()) 239e5c31af7Sopenharmony_ci { 240e5c31af7Sopenharmony_ci case ri::TYPE_RESULT: 241e5c31af7Sopenharmony_ci // Ignored here, written at end. 242e5c31af7Sopenharmony_ci break; 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci case ri::TYPE_TEXT: 245e5c31af7Sopenharmony_ci dst << Writer::BeginElement("Text") << static_cast<const ri::Text&>(item).text << Writer::EndElement; 246e5c31af7Sopenharmony_ci break; 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci case ri::TYPE_NUMBER: 249e5c31af7Sopenharmony_ci { 250e5c31af7Sopenharmony_ci const ri::Number& number = static_cast<const ri::Number&>(item); 251e5c31af7Sopenharmony_ci dst << Writer::BeginElement("Number") 252e5c31af7Sopenharmony_ci << Writer::Attribute("Name", number.name) 253e5c31af7Sopenharmony_ci << Writer::Attribute("Description", number.description) 254e5c31af7Sopenharmony_ci << Writer::Attribute("Unit", number.unit) 255e5c31af7Sopenharmony_ci << Writer::Attribute("Tag", number.tag) 256e5c31af7Sopenharmony_ci << number.value 257e5c31af7Sopenharmony_ci << Writer::EndElement; 258e5c31af7Sopenharmony_ci break; 259e5c31af7Sopenharmony_ci } 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci case ri::TYPE_IMAGE: 262e5c31af7Sopenharmony_ci { 263e5c31af7Sopenharmony_ci const ri::Image& image = static_cast<const ri::Image&>(item); 264e5c31af7Sopenharmony_ci dst << Writer::BeginElement("Image") 265e5c31af7Sopenharmony_ci << Writer::Attribute("Name", image.name) 266e5c31af7Sopenharmony_ci << Writer::Attribute("Description", image.description) 267e5c31af7Sopenharmony_ci << Writer::Attribute("Width", de::toString(image.width)) 268e5c31af7Sopenharmony_ci << Writer::Attribute("Height", de::toString(image.height)) 269e5c31af7Sopenharmony_ci << Writer::Attribute("Format", getImageFormatName(image.format)) 270e5c31af7Sopenharmony_ci << Writer::Attribute("CompressionMode", getImageCompressionName(image.compression)) 271e5c31af7Sopenharmony_ci << toBase64(&image.data[0], (int)image.data.size()) 272e5c31af7Sopenharmony_ci << Writer::EndElement; 273e5c31af7Sopenharmony_ci break; 274e5c31af7Sopenharmony_ci } 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci case ri::TYPE_IMAGESET: 277e5c31af7Sopenharmony_ci { 278e5c31af7Sopenharmony_ci const ri::ImageSet& imageSet = static_cast<const ri::ImageSet&>(item); 279e5c31af7Sopenharmony_ci dst << Writer::BeginElement("ImageSet") 280e5c31af7Sopenharmony_ci << Writer::Attribute("Name", imageSet.name) 281e5c31af7Sopenharmony_ci << Writer::Attribute("Description", imageSet.description); 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < imageSet.images.getNumItems(); ndx++) 284e5c31af7Sopenharmony_ci writeResultItem(imageSet.images.getItem(ndx), dst); 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ci dst << Writer::EndElement; 287e5c31af7Sopenharmony_ci break; 288e5c31af7Sopenharmony_ci } 289e5c31af7Sopenharmony_ci 290e5c31af7Sopenharmony_ci case ri::TYPE_SHADER: 291e5c31af7Sopenharmony_ci { 292e5c31af7Sopenharmony_ci const ri::Shader& shader = static_cast<const ri::Shader&>(item); 293e5c31af7Sopenharmony_ci const char* tagName = DE_NULL; 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_ci switch (shader.shaderType) 296e5c31af7Sopenharmony_ci { 297e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_VERTEX: tagName = "VertexShader"; break; 298e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_FRAGMENT: tagName = "FragmentShader"; break; 299e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_GEOMETRY: tagName = "GeometryShader"; break; 300e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_TESS_CONTROL: tagName = "TessControlShader"; break; 301e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_TESS_EVALUATION: tagName = "TessEvaluationShader"; break; 302e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_COMPUTE: tagName = "ComputeShader"; break; 303e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_RAYGEN: tagName = "RaygenShader"; break; 304e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_ANY_HIT: tagName = "AnyHitShader"; break; 305e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_CLOSEST_HIT: tagName = "ClosestHitShader"; break; 306e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_MISS: tagName = "MissShader"; break; 307e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_INTERSECTION: tagName = "IntersectionShader"; break; 308e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_CALLABLE: tagName = "CallableShader"; break; 309e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_TASK: tagName = "TaskShader"; break; 310e5c31af7Sopenharmony_ci case ri::Shader::SHADERTYPE_MESH: tagName = "MeshShader"; break; 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci default: 313e5c31af7Sopenharmony_ci throw Error("Unknown shader type"); 314e5c31af7Sopenharmony_ci } 315e5c31af7Sopenharmony_ci 316e5c31af7Sopenharmony_ci dst << Writer::BeginElement(tagName) 317e5c31af7Sopenharmony_ci << Writer::Attribute("CompileStatus", getStatusName(shader.compileStatus)); 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci writeResultItem(shader.source, dst); 320e5c31af7Sopenharmony_ci writeResultItem(shader.infoLog, dst); 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_ci dst << Writer::EndElement; 323e5c31af7Sopenharmony_ci break; 324e5c31af7Sopenharmony_ci } 325e5c31af7Sopenharmony_ci 326e5c31af7Sopenharmony_ci case ri::TYPE_SHADERPROGRAM: 327e5c31af7Sopenharmony_ci { 328e5c31af7Sopenharmony_ci const ri::ShaderProgram& program = static_cast<const ri::ShaderProgram&>(item); 329e5c31af7Sopenharmony_ci dst << Writer::BeginElement("ShaderProgram") 330e5c31af7Sopenharmony_ci << Writer::Attribute("LinkStatus", getStatusName(program.linkStatus)); 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci writeResultItem(program.linkInfoLog, dst); 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < program.shaders.getNumItems(); ndx++) 335e5c31af7Sopenharmony_ci writeResultItem(program.shaders.getItem(ndx), dst); 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci dst << Writer::EndElement; 338e5c31af7Sopenharmony_ci break; 339e5c31af7Sopenharmony_ci } 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci case ri::TYPE_SHADERSOURCE: 342e5c31af7Sopenharmony_ci dst << Writer::BeginElement("ShaderSource") << static_cast<const ri::ShaderSource&>(item).source << Writer::EndElement; 343e5c31af7Sopenharmony_ci break; 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci case ri::TYPE_SPIRVSOURCE: 346e5c31af7Sopenharmony_ci dst << Writer::BeginElement("SpirVAssemblySource") << static_cast<const ri::SpirVSource&>(item).source << Writer::EndElement; 347e5c31af7Sopenharmony_ci break; 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci case ri::TYPE_INFOLOG: 350e5c31af7Sopenharmony_ci dst << Writer::BeginElement("InfoLog") << static_cast<const ri::InfoLog&>(item).log << Writer::EndElement; 351e5c31af7Sopenharmony_ci break; 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci case ri::TYPE_SECTION: 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci const ri::Section& section = static_cast<const ri::Section&>(item); 356e5c31af7Sopenharmony_ci dst << Writer::BeginElement("Section") 357e5c31af7Sopenharmony_ci << Writer::Attribute("Name", section.name) 358e5c31af7Sopenharmony_ci << Writer::Attribute("Description", section.description); 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < section.items.getNumItems(); ndx++) 361e5c31af7Sopenharmony_ci writeResultItem(section.items.getItem(ndx), dst); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci dst << Writer::EndElement; 364e5c31af7Sopenharmony_ci break; 365e5c31af7Sopenharmony_ci } 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci case ri::TYPE_KERNELSOURCE: 368e5c31af7Sopenharmony_ci dst << Writer::BeginElement("KernelSource") << static_cast<const ri::KernelSource&>(item).source << Writer::EndElement; 369e5c31af7Sopenharmony_ci break; 370e5c31af7Sopenharmony_ci 371e5c31af7Sopenharmony_ci case ri::TYPE_COMPILEINFO: 372e5c31af7Sopenharmony_ci { 373e5c31af7Sopenharmony_ci const ri::CompileInfo& compileInfo = static_cast<const ri::CompileInfo&>(item); 374e5c31af7Sopenharmony_ci dst << Writer::BeginElement("CompileInfo") 375e5c31af7Sopenharmony_ci << Writer::Attribute("Name", compileInfo.name) 376e5c31af7Sopenharmony_ci << Writer::Attribute("Description", compileInfo.description) 377e5c31af7Sopenharmony_ci << Writer::Attribute("CompileStatus", getStatusName(compileInfo.compileStatus)); 378e5c31af7Sopenharmony_ci 379e5c31af7Sopenharmony_ci writeResultItem(compileInfo.infoLog, dst); 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci dst << Writer::EndElement; 382e5c31af7Sopenharmony_ci break; 383e5c31af7Sopenharmony_ci } 384e5c31af7Sopenharmony_ci 385e5c31af7Sopenharmony_ci case ri::TYPE_EGLCONFIG: 386e5c31af7Sopenharmony_ci { 387e5c31af7Sopenharmony_ci const ri::EglConfig& config = static_cast<const ri::EglConfig&>(item); 388e5c31af7Sopenharmony_ci dst << Writer::BeginElement("EglConfig") 389e5c31af7Sopenharmony_ci << Writer::Attribute("BufferSize", de::toString(config.bufferSize)) 390e5c31af7Sopenharmony_ci << Writer::Attribute("RedSize", de::toString(config.redSize)) 391e5c31af7Sopenharmony_ci << Writer::Attribute("GreenSize", de::toString(config.greenSize)) 392e5c31af7Sopenharmony_ci << Writer::Attribute("BlueSize", de::toString(config.blueSize)) 393e5c31af7Sopenharmony_ci << Writer::Attribute("LuminanceSize", de::toString(config.luminanceSize)) 394e5c31af7Sopenharmony_ci << Writer::Attribute("AlphaSize", de::toString(config.alphaSize)) 395e5c31af7Sopenharmony_ci << Writer::Attribute("AlphaMaskSize", de::toString(config.alphaMaskSize)) 396e5c31af7Sopenharmony_ci << Writer::Attribute("BindToTextureRGB", getBoolName(config.bindToTextureRGB)) 397e5c31af7Sopenharmony_ci << Writer::Attribute("BindToTextureRGBA", getBoolName(config.bindToTextureRGBA)) 398e5c31af7Sopenharmony_ci << Writer::Attribute("ColorBufferType", config.colorBufferType) 399e5c31af7Sopenharmony_ci << Writer::Attribute("ConfigCaveat", config.configCaveat) 400e5c31af7Sopenharmony_ci << Writer::Attribute("ConfigID", de::toString(config.configID)) 401e5c31af7Sopenharmony_ci << Writer::Attribute("Conformant", config.conformant) 402e5c31af7Sopenharmony_ci << Writer::Attribute("DepthSize", de::toString(config.depthSize)) 403e5c31af7Sopenharmony_ci << Writer::Attribute("Level", de::toString(config.level)) 404e5c31af7Sopenharmony_ci << Writer::Attribute("MaxPBufferWidth", de::toString(config.maxPBufferWidth)) 405e5c31af7Sopenharmony_ci << Writer::Attribute("MaxPBufferHeight", de::toString(config.maxPBufferHeight)) 406e5c31af7Sopenharmony_ci << Writer::Attribute("MaxPBufferPixels", de::toString(config.maxPBufferPixels)) 407e5c31af7Sopenharmony_ci << Writer::Attribute("MaxSwapInterval", de::toString(config.maxSwapInterval)) 408e5c31af7Sopenharmony_ci << Writer::Attribute("MinSwapInterval", de::toString(config.minSwapInterval)) 409e5c31af7Sopenharmony_ci << Writer::Attribute("NativeRenderable", getBoolName(config.nativeRenderable)) 410e5c31af7Sopenharmony_ci << Writer::Attribute("RenderableType", config.renderableType) 411e5c31af7Sopenharmony_ci << Writer::Attribute("SampleBuffers", de::toString(config.sampleBuffers)) 412e5c31af7Sopenharmony_ci << Writer::Attribute("Samples", de::toString(config.samples)) 413e5c31af7Sopenharmony_ci << Writer::Attribute("StencilSize", de::toString(config.stencilSize)) 414e5c31af7Sopenharmony_ci << Writer::Attribute("SurfaceTypes", config.surfaceTypes) 415e5c31af7Sopenharmony_ci << Writer::Attribute("TransparentType", config.transparentType) 416e5c31af7Sopenharmony_ci << Writer::Attribute("TransparentRedValue", de::toString(config.transparentRedValue)) 417e5c31af7Sopenharmony_ci << Writer::Attribute("TransparentGreenValue", de::toString(config.transparentGreenValue)) 418e5c31af7Sopenharmony_ci << Writer::Attribute("TransparentBlueValue", de::toString(config.transparentBlueValue)) 419e5c31af7Sopenharmony_ci << Writer::EndElement; 420e5c31af7Sopenharmony_ci break; 421e5c31af7Sopenharmony_ci } 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci case ri::TYPE_EGLCONFIGSET: 424e5c31af7Sopenharmony_ci { 425e5c31af7Sopenharmony_ci const ri::EglConfigSet& configSet = static_cast<const ri::EglConfigSet&>(item); 426e5c31af7Sopenharmony_ci dst << Writer::BeginElement("EglConfigSet") 427e5c31af7Sopenharmony_ci << Writer::Attribute("Name", configSet.name) 428e5c31af7Sopenharmony_ci << Writer::Attribute("Description", configSet.description); 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < configSet.configs.getNumItems(); ndx++) 431e5c31af7Sopenharmony_ci writeResultItem(configSet.configs.getItem(ndx), dst); 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci dst << Writer::EndElement; 434e5c31af7Sopenharmony_ci break; 435e5c31af7Sopenharmony_ci } 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLELIST: 438e5c31af7Sopenharmony_ci { 439e5c31af7Sopenharmony_ci const ri::SampleList& list = static_cast<const ri::SampleList&>(item); 440e5c31af7Sopenharmony_ci dst << Writer::BeginElement("SampleList") 441e5c31af7Sopenharmony_ci << Writer::Attribute("Name", list.name) 442e5c31af7Sopenharmony_ci << Writer::Attribute("Description", list.description); 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci writeResultItem(list.sampleInfo, dst); 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < list.samples.getNumItems(); ndx++) 447e5c31af7Sopenharmony_ci writeResultItem(list.samples.getItem(ndx), dst); 448e5c31af7Sopenharmony_ci 449e5c31af7Sopenharmony_ci dst << Writer::EndElement; 450e5c31af7Sopenharmony_ci break; 451e5c31af7Sopenharmony_ci } 452e5c31af7Sopenharmony_ci 453e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLEINFO: 454e5c31af7Sopenharmony_ci { 455e5c31af7Sopenharmony_ci const ri::SampleInfo& info = static_cast<const ri::SampleInfo&>(item); 456e5c31af7Sopenharmony_ci dst << Writer::BeginElement("SampleInfo"); 457e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < info.valueInfos.getNumItems(); ndx++) 458e5c31af7Sopenharmony_ci writeResultItem(info.valueInfos.getItem(ndx), dst); 459e5c31af7Sopenharmony_ci dst << Writer::EndElement; 460e5c31af7Sopenharmony_ci break; 461e5c31af7Sopenharmony_ci } 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci case ri::TYPE_VALUEINFO: 464e5c31af7Sopenharmony_ci { 465e5c31af7Sopenharmony_ci const ri::ValueInfo& info = static_cast<const ri::ValueInfo&>(item); 466e5c31af7Sopenharmony_ci dst << Writer::BeginElement("ValueInfo") 467e5c31af7Sopenharmony_ci << Writer::Attribute("Name", info.name) 468e5c31af7Sopenharmony_ci << Writer::Attribute("Description", info.description) 469e5c31af7Sopenharmony_ci << Writer::Attribute("Tag", getSampleValueTagName(info.tag)); 470e5c31af7Sopenharmony_ci if (!info.unit.empty()) 471e5c31af7Sopenharmony_ci dst << Writer::Attribute("Unit", info.unit); 472e5c31af7Sopenharmony_ci dst << Writer::EndElement; 473e5c31af7Sopenharmony_ci break; 474e5c31af7Sopenharmony_ci } 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLE: 477e5c31af7Sopenharmony_ci { 478e5c31af7Sopenharmony_ci const ri::Sample& sample = static_cast<const ri::Sample&>(item); 479e5c31af7Sopenharmony_ci dst << Writer::BeginElement("Sample"); 480e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < sample.values.getNumItems(); ndx++) 481e5c31af7Sopenharmony_ci writeResultItem(sample.values.getItem(ndx), dst); 482e5c31af7Sopenharmony_ci dst << Writer::EndElement; 483e5c31af7Sopenharmony_ci break; 484e5c31af7Sopenharmony_ci } 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci case ri::TYPE_SAMPLEVALUE: 487e5c31af7Sopenharmony_ci { 488e5c31af7Sopenharmony_ci const ri::SampleValue& value = static_cast<const ri::SampleValue&>(item); 489e5c31af7Sopenharmony_ci dst << Writer::BeginElement("Value") 490e5c31af7Sopenharmony_ci << value.value 491e5c31af7Sopenharmony_ci << Writer::EndElement; 492e5c31af7Sopenharmony_ci break; 493e5c31af7Sopenharmony_ci } 494e5c31af7Sopenharmony_ci 495e5c31af7Sopenharmony_ci default: 496e5c31af7Sopenharmony_ci XE_FAIL("Unsupported result item"); 497e5c31af7Sopenharmony_ci } 498e5c31af7Sopenharmony_ci} 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_civoid writeTestResult (const TestCaseResult& result, xe::xml::Writer& xmlWriter) 501e5c31af7Sopenharmony_ci{ 502e5c31af7Sopenharmony_ci using xml::Writer; 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_ci xmlWriter << Writer::BeginElement("TestCaseResult") 505e5c31af7Sopenharmony_ci << Writer::Attribute("Version", result.caseVersion) 506e5c31af7Sopenharmony_ci << Writer::Attribute("CasePath", result.casePath) 507e5c31af7Sopenharmony_ci << Writer::Attribute("CaseType", getTestCaseTypeName(result.caseType)); 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < result.resultItems.getNumItems(); ndx++) 510e5c31af7Sopenharmony_ci writeResultItem(result.resultItems.getItem(ndx), xmlWriter); 511e5c31af7Sopenharmony_ci 512e5c31af7Sopenharmony_ci // Result item is not logged until end. 513e5c31af7Sopenharmony_ci xmlWriter << Writer::BeginElement("Result") 514e5c31af7Sopenharmony_ci << Writer::Attribute("StatusCode", getTestStatusCodeName(result.statusCode)) 515e5c31af7Sopenharmony_ci << result.statusDetails 516e5c31af7Sopenharmony_ci << Writer::EndElement; 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci xmlWriter << Writer::EndElement; 519e5c31af7Sopenharmony_ci} 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_civoid writeTestResult (const TestCaseResult& result, std::ostream& stream) 522e5c31af7Sopenharmony_ci{ 523e5c31af7Sopenharmony_ci xml::Writer xmlWriter(stream); 524e5c31af7Sopenharmony_ci stream << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; 525e5c31af7Sopenharmony_ci writeTestResult(result, xmlWriter); 526e5c31af7Sopenharmony_ci} 527e5c31af7Sopenharmony_ci 528e5c31af7Sopenharmony_civoid writeTestResultToFile (const TestCaseResult& result, const char* filename) 529e5c31af7Sopenharmony_ci{ 530e5c31af7Sopenharmony_ci std::ofstream str(filename, std::ofstream::binary|std::ofstream::trunc); 531e5c31af7Sopenharmony_ci writeTestResult(result, str); 532e5c31af7Sopenharmony_ci str.close(); 533e5c31af7Sopenharmony_ci} 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci} // xe 536