1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core 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 C++ Wrapper. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "deCommandLine.h" 25e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 26e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 27e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 28e5c31af7Sopenharmony_ci#include "deMath.h" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include <limits> 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_cinamespace tcu 33e5c31af7Sopenharmony_ci{ 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ciclass LogWriteFailedError : public ResourceError 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_cipublic: 38e5c31af7Sopenharmony_ci LogWriteFailedError (void) : ResourceError("Writing to test log failed") {} 39e5c31af7Sopenharmony_ci}; 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_cienum 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_ci MAX_IMAGE_SIZE_2D = 4096, 44e5c31af7Sopenharmony_ci MAX_IMAGE_SIZE_3D = 128 45e5c31af7Sopenharmony_ci}; 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ci// LogImage 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciLogImage::LogImage (const std::string& name, const std::string& description, const Surface& surface, qpImageCompressionMode compression) 50e5c31af7Sopenharmony_ci : m_name (name) 51e5c31af7Sopenharmony_ci , m_description (description) 52e5c31af7Sopenharmony_ci , m_access (surface.getAccess()) 53e5c31af7Sopenharmony_ci , m_scale (1.0f, 1.0f, 1.0f, 1.0f) 54e5c31af7Sopenharmony_ci , m_bias (0.0f, 0.0f, 0.0f, 0.0f) 55e5c31af7Sopenharmony_ci , m_compression (compression) 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_ci} 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ciLogImage::LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, qpImageCompressionMode compression) 60e5c31af7Sopenharmony_ci : m_name (name) 61e5c31af7Sopenharmony_ci , m_description (description) 62e5c31af7Sopenharmony_ci , m_access (access) 63e5c31af7Sopenharmony_ci , m_scale (1.0f, 1.0f, 1.0f, 1.0f) 64e5c31af7Sopenharmony_ci , m_bias (0.0f, 0.0f, 0.0f, 0.0f) 65e5c31af7Sopenharmony_ci , m_compression (compression) 66e5c31af7Sopenharmony_ci{ 67e5c31af7Sopenharmony_ci // Simplify combined formats that only use a single channel 68e5c31af7Sopenharmony_ci if (tcu::isCombinedDepthStencilType(m_access.getFormat().type)) 69e5c31af7Sopenharmony_ci { 70e5c31af7Sopenharmony_ci if (m_access.getFormat().order == tcu::TextureFormat::D) 71e5c31af7Sopenharmony_ci m_access = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_DEPTH); 72e5c31af7Sopenharmony_ci else if (m_access.getFormat().order == tcu::TextureFormat::S) 73e5c31af7Sopenharmony_ci m_access = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_STENCIL); 74e5c31af7Sopenharmony_ci } 75e5c31af7Sopenharmony_ci 76e5c31af7Sopenharmony_ci // Implicit scale and bias 77e5c31af7Sopenharmony_ci if (m_access.getFormat().order != tcu::TextureFormat::DS) 78e5c31af7Sopenharmony_ci computePixelScaleBias(m_access, m_scale, m_bias); 79e5c31af7Sopenharmony_ci else 80e5c31af7Sopenharmony_ci { 81e5c31af7Sopenharmony_ci // Pack D and S bias and scale to R and G 82e5c31af7Sopenharmony_ci const ConstPixelBufferAccess depthAccess = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_DEPTH); 83e5c31af7Sopenharmony_ci const ConstPixelBufferAccess stencilAccess = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_STENCIL); 84e5c31af7Sopenharmony_ci tcu::Vec4 depthScale; 85e5c31af7Sopenharmony_ci tcu::Vec4 depthBias; 86e5c31af7Sopenharmony_ci tcu::Vec4 stencilScale; 87e5c31af7Sopenharmony_ci tcu::Vec4 stencilBias; 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci computePixelScaleBias(depthAccess, depthScale, depthBias); 90e5c31af7Sopenharmony_ci computePixelScaleBias(stencilAccess, stencilScale, stencilBias); 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ci m_scale = tcu::Vec4(depthScale.x(), stencilScale.x(), 0.0f, 0.0f); 93e5c31af7Sopenharmony_ci m_bias = tcu::Vec4(depthBias.x(), stencilBias.x(), 0.0f, 0.0f); 94e5c31af7Sopenharmony_ci } 95e5c31af7Sopenharmony_ci} 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ciLogImage::LogImage (const std::string& name, const std::string& description, const ConstPixelBufferAccess& access, const Vec4& scale, const Vec4& bias, qpImageCompressionMode compression) 98e5c31af7Sopenharmony_ci : m_name (name) 99e5c31af7Sopenharmony_ci , m_description (description) 100e5c31af7Sopenharmony_ci , m_access (access) 101e5c31af7Sopenharmony_ci , m_scale (scale) 102e5c31af7Sopenharmony_ci , m_bias (bias) 103e5c31af7Sopenharmony_ci , m_compression (compression) 104e5c31af7Sopenharmony_ci{ 105e5c31af7Sopenharmony_ci // Cannot set scale and bias of combined formats 106e5c31af7Sopenharmony_ci DE_ASSERT(access.getFormat().order != tcu::TextureFormat::DS); 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ci // Simplify access 109e5c31af7Sopenharmony_ci if (tcu::isCombinedDepthStencilType(access.getFormat().type)) 110e5c31af7Sopenharmony_ci { 111e5c31af7Sopenharmony_ci if (access.getFormat().order == tcu::TextureFormat::D) 112e5c31af7Sopenharmony_ci m_access = tcu::getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_DEPTH); 113e5c31af7Sopenharmony_ci if (access.getFormat().order == tcu::TextureFormat::S) 114e5c31af7Sopenharmony_ci m_access = tcu::getEffectiveDepthStencilAccess(access, tcu::Sampler::MODE_STENCIL); 115e5c31af7Sopenharmony_ci else 116e5c31af7Sopenharmony_ci { 117e5c31af7Sopenharmony_ci // Cannot log a DS format 118e5c31af7Sopenharmony_ci DE_ASSERT(false); 119e5c31af7Sopenharmony_ci return; 120e5c31af7Sopenharmony_ci } 121e5c31af7Sopenharmony_ci } 122e5c31af7Sopenharmony_ci} 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_civoid LogImage::write (TestLog& log) const 125e5c31af7Sopenharmony_ci{ 126e5c31af7Sopenharmony_ci if (m_access.getFormat().order != tcu::TextureFormat::DS) 127e5c31af7Sopenharmony_ci log.writeImage(m_name.c_str(), m_description.c_str(), m_access, m_scale, m_bias, m_compression); 128e5c31af7Sopenharmony_ci else 129e5c31af7Sopenharmony_ci { 130e5c31af7Sopenharmony_ci const ConstPixelBufferAccess depthAccess = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_DEPTH); 131e5c31af7Sopenharmony_ci const ConstPixelBufferAccess stencilAccess = tcu::getEffectiveDepthStencilAccess(m_access, tcu::Sampler::MODE_STENCIL); 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci log.startImageSet(m_name.c_str(), m_description.c_str()); 134e5c31af7Sopenharmony_ci log.writeImage("Depth", "Depth channel", depthAccess, m_scale.swizzle(0, 0, 0, 0), m_bias.swizzle(0, 0, 0, 0), m_compression); 135e5c31af7Sopenharmony_ci log.writeImage("Stencil", "Stencil channel", stencilAccess, m_scale.swizzle(1, 1, 1, 1), m_bias.swizzle(1, 1, 1, 1), m_compression); 136e5c31af7Sopenharmony_ci log.endImageSet(); 137e5c31af7Sopenharmony_ci } 138e5c31af7Sopenharmony_ci} 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci// MessageBuilder 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ciMessageBuilder::MessageBuilder (const MessageBuilder& other) 143e5c31af7Sopenharmony_ci : m_log(other.m_log) 144e5c31af7Sopenharmony_ci{ 145e5c31af7Sopenharmony_ci m_str.str(other.m_str.str()); 146e5c31af7Sopenharmony_ci} 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ciMessageBuilder& MessageBuilder::operator= (const MessageBuilder& other) 149e5c31af7Sopenharmony_ci{ 150e5c31af7Sopenharmony_ci m_log = other.m_log; 151e5c31af7Sopenharmony_ci m_str.str(other.m_str.str()); 152e5c31af7Sopenharmony_ci return *this; 153e5c31af7Sopenharmony_ci} 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ciTestLog& MessageBuilder::operator<< (const TestLog::EndMessageToken&) 156e5c31af7Sopenharmony_ci{ 157e5c31af7Sopenharmony_ci m_log->writeMessage(m_str.str().c_str()); 158e5c31af7Sopenharmony_ci return *m_log; 159e5c31af7Sopenharmony_ci} 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_ci// SampleBuilder 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ciTestLog& SampleBuilder::operator<< (const TestLog::EndSampleToken&) 164e5c31af7Sopenharmony_ci{ 165e5c31af7Sopenharmony_ci m_log->startSample(); 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci for (std::vector<Value>::const_iterator val = m_values.begin(); val != m_values.end(); ++val) 168e5c31af7Sopenharmony_ci { 169e5c31af7Sopenharmony_ci if (val->type == Value::TYPE_FLOAT64) 170e5c31af7Sopenharmony_ci m_log->writeSampleValue(val->value.float64); 171e5c31af7Sopenharmony_ci else if (val->type == Value::TYPE_INT64) 172e5c31af7Sopenharmony_ci m_log->writeSampleValue(val->value.int64); 173e5c31af7Sopenharmony_ci else 174e5c31af7Sopenharmony_ci DE_ASSERT(false); 175e5c31af7Sopenharmony_ci } 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci m_log->endSample(); 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci return *m_log; 180e5c31af7Sopenharmony_ci} 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci// TestLog 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ciTestLog::TestLog (const char* fileName, deUint32 flags) 185e5c31af7Sopenharmony_ci : m_log(qpTestLog_createFileLog(fileName, flags)), m_logSupressed(false) 186e5c31af7Sopenharmony_ci{ 187e5c31af7Sopenharmony_ci if (!m_log) 188e5c31af7Sopenharmony_ci throw ResourceError(std::string("Failed to open test log file '") + fileName + "'"); 189e5c31af7Sopenharmony_ci} 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_civoid TestLog::writeSessionInfo(std::string additionalInfo) 192e5c31af7Sopenharmony_ci{ 193e5c31af7Sopenharmony_ci qpTestLog_beginSession(m_log, additionalInfo.c_str()); 194e5c31af7Sopenharmony_ci} 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ciTestLog::~TestLog (void) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci qpTestLog_destroy(m_log); 199e5c31af7Sopenharmony_ci} 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_civoid TestLog::writeMessage (const char* msgStr) 202e5c31af7Sopenharmony_ci{ 203e5c31af7Sopenharmony_ci if (m_logSupressed) return; 204e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 205e5c31af7Sopenharmony_ci if (qpTestLog_writeText(m_log, DE_NULL, DE_NULL, QP_KEY_TAG_NONE, msgStr) == DE_FALSE) 206e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 207e5c31af7Sopenharmony_ci} 208e5c31af7Sopenharmony_ci 209e5c31af7Sopenharmony_civoid TestLog::startImageSet (const char* name, const char* description) 210e5c31af7Sopenharmony_ci{ 211e5c31af7Sopenharmony_ci if (m_logSupressed) return; 212e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 213e5c31af7Sopenharmony_ci if (qpTestLog_startImageSet(m_log, name, description) == DE_FALSE) 214e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 215e5c31af7Sopenharmony_ci} 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_civoid TestLog::endImageSet (void) 218e5c31af7Sopenharmony_ci{ 219e5c31af7Sopenharmony_ci if (m_logSupressed) return; 220e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 221e5c31af7Sopenharmony_ci if (qpTestLog_endImageSet(m_log) == DE_FALSE) 222e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 223e5c31af7Sopenharmony_ci} 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_citemplate <int Size> 226e5c31af7Sopenharmony_cistatic Vector<int, Size> computeScaledSize (const Vector<int, Size>& imageSize, int maxSize) 227e5c31af7Sopenharmony_ci{ 228e5c31af7Sopenharmony_ci bool allInRange = true; 229e5c31af7Sopenharmony_ci for (int i = 0; i < Size; i++) 230e5c31af7Sopenharmony_ci allInRange = allInRange && (imageSize[i] <= maxSize); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci if (allInRange) 233e5c31af7Sopenharmony_ci return imageSize; 234e5c31af7Sopenharmony_ci else 235e5c31af7Sopenharmony_ci { 236e5c31af7Sopenharmony_ci float d = 1.0f; 237e5c31af7Sopenharmony_ci for (int i = 0; i < Size; i++) 238e5c31af7Sopenharmony_ci d = de::max(d, (float)imageSize[i] / (float)maxSize); 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ci Vector<int, Size> res; 241e5c31af7Sopenharmony_ci for (int i = 0; i < Size; i++) 242e5c31af7Sopenharmony_ci res[i] = de::max(1, deRoundFloatToInt32((float)imageSize[i] / d)); 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci return res; 245e5c31af7Sopenharmony_ci } 246e5c31af7Sopenharmony_ci} 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_civoid TestLog::writeImage (const char* name, const char* description, const ConstPixelBufferAccess& access, const Vec4& pixelScale, const Vec4& pixelBias, qpImageCompressionMode compressionMode) 249e5c31af7Sopenharmony_ci{ 250e5c31af7Sopenharmony_ci if (m_logSupressed) return; 251e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 252e5c31af7Sopenharmony_ci const TextureFormat& format = access.getFormat(); 253e5c31af7Sopenharmony_ci int width = access.getWidth(); 254e5c31af7Sopenharmony_ci int height = access.getHeight(); 255e5c31af7Sopenharmony_ci int depth = access.getDepth(); 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci // Writing a combined image does not make sense 258e5c31af7Sopenharmony_ci DE_ASSERT(!tcu::isCombinedDepthStencilType(access.getFormat().type)); 259e5c31af7Sopenharmony_ci 260e5c31af7Sopenharmony_ci // Do not bother with preprocessing if images are not stored 261e5c31af7Sopenharmony_ci if ((qpTestLog_getLogFlags(m_log) & QP_TEST_LOG_EXCLUDE_IMAGES) != 0) 262e5c31af7Sopenharmony_ci return; 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_ci if (depth == 1 && (format.type == TextureFormat::UNORM_INT8 || format.type == TextureFormat::UNSIGNED_INT8) 265e5c31af7Sopenharmony_ci && width <= MAX_IMAGE_SIZE_2D && height <= MAX_IMAGE_SIZE_2D 266e5c31af7Sopenharmony_ci && (format.order == TextureFormat::RGB || format.order == TextureFormat::RGBA) 267e5c31af7Sopenharmony_ci && access.getPixelPitch() == access.getFormat().getPixelSize() 268e5c31af7Sopenharmony_ci && pixelBias[0] == 0.0f && pixelBias[1] == 0.0f && pixelBias[2] == 0.0f && pixelBias[3] == 0.0f 269e5c31af7Sopenharmony_ci && pixelScale[0] == 1.0f && pixelScale[1] == 1.0f && pixelScale[2] == 1.0f && pixelScale[3] == 1.0f) 270e5c31af7Sopenharmony_ci { 271e5c31af7Sopenharmony_ci // Fast-path. 272e5c31af7Sopenharmony_ci bool isRGBA = format.order == TextureFormat::RGBA; 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ci writeImage(name, description, compressionMode, 275e5c31af7Sopenharmony_ci isRGBA ? QP_IMAGE_FORMAT_RGBA8888 : QP_IMAGE_FORMAT_RGB888, 276e5c31af7Sopenharmony_ci width, height, access.getRowPitch(), access.getDataPtr()); 277e5c31af7Sopenharmony_ci } 278e5c31af7Sopenharmony_ci else if (depth == 1) 279e5c31af7Sopenharmony_ci { 280e5c31af7Sopenharmony_ci Sampler sampler (Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::LINEAR, Sampler::NEAREST); 281e5c31af7Sopenharmony_ci IVec2 logImageSize = computeScaledSize(IVec2(width, height), MAX_IMAGE_SIZE_2D); 282e5c31af7Sopenharmony_ci tcu::TextureLevel logImage (TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), logImageSize.x(), logImageSize.y(), 1); 283e5c31af7Sopenharmony_ci PixelBufferAccess logImageAccess = logImage.getAccess(); 284e5c31af7Sopenharmony_ci std::ostringstream longDesc; 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ci longDesc << description << " (p' = p * " << pixelScale << " + " << pixelBias << ")"; 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci for (int y = 0; y < logImage.getHeight(); y++) 289e5c31af7Sopenharmony_ci { 290e5c31af7Sopenharmony_ci for (int x = 0; x < logImage.getWidth(); x++) 291e5c31af7Sopenharmony_ci { 292e5c31af7Sopenharmony_ci float yf = ((float)y + 0.5f) / (float)logImage.getHeight(); 293e5c31af7Sopenharmony_ci float xf = ((float)x + 0.5f) / (float)logImage.getWidth(); 294e5c31af7Sopenharmony_ci Vec4 s = access.sample2D(sampler, sampler.minFilter, xf, yf, 0)*pixelScale + pixelBias; 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ci logImageAccess.setPixel(s, x, y); 297e5c31af7Sopenharmony_ci } 298e5c31af7Sopenharmony_ci } 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci writeImage(name, longDesc.str().c_str(), compressionMode, QP_IMAGE_FORMAT_RGBA8888, 301e5c31af7Sopenharmony_ci logImageAccess.getWidth(), logImageAccess.getHeight(), logImageAccess.getRowPitch(), 302e5c31af7Sopenharmony_ci logImageAccess.getDataPtr()); 303e5c31af7Sopenharmony_ci } 304e5c31af7Sopenharmony_ci else 305e5c31af7Sopenharmony_ci { 306e5c31af7Sopenharmony_ci // Isometric splat volume rendering. 307e5c31af7Sopenharmony_ci const float blendFactor = 0.85f; 308e5c31af7Sopenharmony_ci IVec3 scaledSize = computeScaledSize(IVec3(width, height, depth), MAX_IMAGE_SIZE_3D); 309e5c31af7Sopenharmony_ci int w = scaledSize.x(); 310e5c31af7Sopenharmony_ci int h = scaledSize.y(); 311e5c31af7Sopenharmony_ci int d = scaledSize.z(); 312e5c31af7Sopenharmony_ci int logImageW = w+d - 1; 313e5c31af7Sopenharmony_ci int logImageH = w+d+h; 314e5c31af7Sopenharmony_ci std::vector<float> blendImage (logImageW*logImageH*4, 0.0f); 315e5c31af7Sopenharmony_ci PixelBufferAccess blendImageAccess (TextureFormat(TextureFormat::RGBA, TextureFormat::FLOAT), logImageW, logImageH, 1, &blendImage[0]); 316e5c31af7Sopenharmony_ci tcu::TextureLevel logImage (TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), logImageW, logImageH, 1); 317e5c31af7Sopenharmony_ci PixelBufferAccess logImageAccess = logImage.getAccess(); 318e5c31af7Sopenharmony_ci Sampler sampler (Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST); 319e5c31af7Sopenharmony_ci std::ostringstream longDesc; 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci // \note Back-to-front. 322e5c31af7Sopenharmony_ci for (int z = d-1; z >= 0; z--) 323e5c31af7Sopenharmony_ci { 324e5c31af7Sopenharmony_ci for (int y = 0; y < h; y++) 325e5c31af7Sopenharmony_ci { 326e5c31af7Sopenharmony_ci for (int x = 0; x < w; x++) 327e5c31af7Sopenharmony_ci { 328e5c31af7Sopenharmony_ci int px = w - (x + 1) + z; 329e5c31af7Sopenharmony_ci int py = (w + d + h) - (x + y + z + 1); 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci float xf = ((float)x + 0.5f) / (float)w; 332e5c31af7Sopenharmony_ci float yf = ((float)y + 0.5f) / (float)h; 333e5c31af7Sopenharmony_ci float zf = ((float)z + 0.5f) / (float)d; 334e5c31af7Sopenharmony_ci 335e5c31af7Sopenharmony_ci Vec4 p = blendImageAccess.getPixel(px, py); 336e5c31af7Sopenharmony_ci Vec4 s = access.sample3D(sampler, sampler.minFilter, xf, yf, zf); 337e5c31af7Sopenharmony_ci Vec4 b = s + p*blendFactor; 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_ci blendImageAccess.setPixel(b, px, py); 340e5c31af7Sopenharmony_ci } 341e5c31af7Sopenharmony_ci } 342e5c31af7Sopenharmony_ci } 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci // Scale blend image nicely. 345e5c31af7Sopenharmony_ci longDesc << description << " (p' = p * " << pixelScale << " + " << pixelBias << ")"; 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ci // Write to final image. 348e5c31af7Sopenharmony_ci tcu::clear(logImageAccess, tcu::IVec4(0x33, 0x66, 0x99, 0xff)); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci for (int z = 0; z < d; z++) 351e5c31af7Sopenharmony_ci { 352e5c31af7Sopenharmony_ci for (int y = 0; y < h; y++) 353e5c31af7Sopenharmony_ci { 354e5c31af7Sopenharmony_ci for (int x = 0; x < w; x++) 355e5c31af7Sopenharmony_ci { 356e5c31af7Sopenharmony_ci if (z != 0 && !(x == 0 || y == h-1 || y == h-2)) 357e5c31af7Sopenharmony_ci continue; 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci int px = w - (x + 1) + z; 360e5c31af7Sopenharmony_ci int py = (w + d + h) - (x + y + z + 1); 361e5c31af7Sopenharmony_ci Vec4 s = blendImageAccess.getPixel(px, py)*pixelScale + pixelBias; 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci logImageAccess.setPixel(s, px, py); 364e5c31af7Sopenharmony_ci } 365e5c31af7Sopenharmony_ci } 366e5c31af7Sopenharmony_ci } 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci writeImage(name, longDesc.str().c_str(), compressionMode, QP_IMAGE_FORMAT_RGBA8888, 369e5c31af7Sopenharmony_ci logImageAccess.getWidth(), logImageAccess.getHeight(), logImageAccess.getRowPitch(), 370e5c31af7Sopenharmony_ci logImageAccess.getDataPtr()); 371e5c31af7Sopenharmony_ci } 372e5c31af7Sopenharmony_ci} 373e5c31af7Sopenharmony_ci 374e5c31af7Sopenharmony_civoid TestLog::writeImage (const char* name, const char* description, qpImageCompressionMode compressionMode, qpImageFormat format, int width, int height, int stride, const void* data) 375e5c31af7Sopenharmony_ci{ 376e5c31af7Sopenharmony_ci if (m_logSupressed) return; 377e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 378e5c31af7Sopenharmony_ci if (qpTestLog_writeImage(m_log, name, description, compressionMode, format, width, height, stride, data) == DE_FALSE) 379e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 380e5c31af7Sopenharmony_ci} 381e5c31af7Sopenharmony_ci 382e5c31af7Sopenharmony_civoid TestLog::startSection (const char* name, const char* description) 383e5c31af7Sopenharmony_ci{ 384e5c31af7Sopenharmony_ci if (m_logSupressed) return; 385e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 386e5c31af7Sopenharmony_ci if (qpTestLog_startSection(m_log, name, description) == DE_FALSE) 387e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 388e5c31af7Sopenharmony_ci} 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_civoid TestLog::endSection (void) 391e5c31af7Sopenharmony_ci{ 392e5c31af7Sopenharmony_ci if (m_logSupressed) return; 393e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 394e5c31af7Sopenharmony_ci if (qpTestLog_endSection(m_log) == DE_FALSE) 395e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 396e5c31af7Sopenharmony_ci} 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_civoid TestLog::startShaderProgram (bool linkOk, const char* linkInfoLog) 399e5c31af7Sopenharmony_ci{ 400e5c31af7Sopenharmony_ci if (m_logSupressed) return; 401e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 402e5c31af7Sopenharmony_ci if (qpTestLog_startShaderProgram(m_log, linkOk?DE_TRUE:DE_FALSE, linkInfoLog) == DE_FALSE) 403e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 404e5c31af7Sopenharmony_ci} 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_civoid TestLog::endShaderProgram (void) 407e5c31af7Sopenharmony_ci{ 408e5c31af7Sopenharmony_ci if (m_logSupressed) return; 409e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 410e5c31af7Sopenharmony_ci if (qpTestLog_endShaderProgram(m_log) == DE_FALSE) 411e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 412e5c31af7Sopenharmony_ci} 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_civoid TestLog::writeShader (qpShaderType type, const char* source, bool compileOk, const char* infoLog) 415e5c31af7Sopenharmony_ci{ 416e5c31af7Sopenharmony_ci if (m_logSupressed) return; 417e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 418e5c31af7Sopenharmony_ci if (qpTestLog_writeShader(m_log, type, source, compileOk?DE_TRUE:DE_FALSE, infoLog) == DE_FALSE) 419e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 420e5c31af7Sopenharmony_ci} 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_civoid TestLog::writeSpirVAssemblySource (const char* source) 423e5c31af7Sopenharmony_ci{ 424e5c31af7Sopenharmony_ci if (m_logSupressed) return; 425e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 426e5c31af7Sopenharmony_ci if (qpTestLog_writeSpirVAssemblySource(m_log, source) == DE_FALSE) 427e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 428e5c31af7Sopenharmony_ci} 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_civoid TestLog::writeKernelSource (const char* source) 431e5c31af7Sopenharmony_ci{ 432e5c31af7Sopenharmony_ci if (m_logSupressed) return; 433e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 434e5c31af7Sopenharmony_ci if (qpTestLog_writeKernelSource(m_log, source) == DE_FALSE) 435e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 436e5c31af7Sopenharmony_ci} 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_civoid TestLog::writeCompileInfo (const char* name, const char* description, bool compileOk, const char* infoLog) 439e5c31af7Sopenharmony_ci{ 440e5c31af7Sopenharmony_ci if (m_logSupressed) return; 441e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 442e5c31af7Sopenharmony_ci if (qpTestLog_writeCompileInfo(m_log, name, description, compileOk ? DE_TRUE : DE_FALSE, infoLog) == DE_FALSE) 443e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 444e5c31af7Sopenharmony_ci} 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_civoid TestLog::writeFloat (const char* name, const char* description, const char* unit, qpKeyValueTag tag, float value) 447e5c31af7Sopenharmony_ci{ 448e5c31af7Sopenharmony_ci if (m_logSupressed) return; 449e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 450e5c31af7Sopenharmony_ci if (qpTestLog_writeFloat(m_log, name, description, unit, tag, value) == DE_FALSE) 451e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 452e5c31af7Sopenharmony_ci} 453e5c31af7Sopenharmony_ci 454e5c31af7Sopenharmony_civoid TestLog::writeInteger (const char* name, const char* description, const char* unit, qpKeyValueTag tag, deInt64 value) 455e5c31af7Sopenharmony_ci{ 456e5c31af7Sopenharmony_ci if (m_logSupressed) return; 457e5c31af7Sopenharmony_ci if (m_skipAdditionalDataInLog) return; 458e5c31af7Sopenharmony_ci if (qpTestLog_writeInteger(m_log, name, description, unit, tag, value) == DE_FALSE) 459e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 460e5c31af7Sopenharmony_ci} 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_civoid TestLog::startEglConfigSet (const char* name, const char* description) 463e5c31af7Sopenharmony_ci{ 464e5c31af7Sopenharmony_ci if (m_logSupressed) return; 465e5c31af7Sopenharmony_ci if (qpTestLog_startEglConfigSet(m_log, name, description) == DE_FALSE) 466e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 467e5c31af7Sopenharmony_ci} 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_civoid TestLog::writeEglConfig (const qpEglConfigInfo* config) 470e5c31af7Sopenharmony_ci{ 471e5c31af7Sopenharmony_ci if (m_logSupressed) return; 472e5c31af7Sopenharmony_ci if (qpTestLog_writeEglConfig(m_log, config) == DE_FALSE) 473e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 474e5c31af7Sopenharmony_ci} 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_civoid TestLog::endEglConfigSet (void) 477e5c31af7Sopenharmony_ci{ 478e5c31af7Sopenharmony_ci if (m_logSupressed) return; 479e5c31af7Sopenharmony_ci if (qpTestLog_endEglConfigSet(m_log) == DE_FALSE) 480e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 481e5c31af7Sopenharmony_ci} 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_civoid TestLog::startCase (const char* testCasePath, qpTestCaseType testCaseType) 484e5c31af7Sopenharmony_ci{ 485e5c31af7Sopenharmony_ci if (m_logSupressed) return; 486e5c31af7Sopenharmony_ci if (qpTestLog_startCase(m_log, testCasePath, testCaseType) == DE_FALSE) 487e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 488e5c31af7Sopenharmony_ci // Check if the test is one of those we want to print fully in the log 489e5c31af7Sopenharmony_ci m_skipAdditionalDataInLog = false; 490e5c31af7Sopenharmony_ci if (qpTestLog_isCompact(m_log)) 491e5c31af7Sopenharmony_ci { 492e5c31af7Sopenharmony_ci const std::string testCasePathStr = testCasePath; 493e5c31af7Sopenharmony_ci if (testCasePathStr.rfind("dEQP-VK.info.") != 0 494e5c31af7Sopenharmony_ci && testCasePathStr.rfind("dEQP-VK.api.info.") != 0 495e5c31af7Sopenharmony_ci && testCasePathStr.rfind("dEQP-VK.api.version_check.") != 0) 496e5c31af7Sopenharmony_ci { 497e5c31af7Sopenharmony_ci // We can skip writing text, numbers, imagesets, etc. 498e5c31af7Sopenharmony_ci m_skipAdditionalDataInLog = true; 499e5c31af7Sopenharmony_ci } 500e5c31af7Sopenharmony_ci } 501e5c31af7Sopenharmony_ci} 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_civoid TestLog::endCase (qpTestResult result, const char* description) 504e5c31af7Sopenharmony_ci{ 505e5c31af7Sopenharmony_ci if (m_logSupressed) return; 506e5c31af7Sopenharmony_ci if (qpTestLog_endCase(m_log, result, description) == DE_FALSE) 507e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 508e5c31af7Sopenharmony_ci} 509e5c31af7Sopenharmony_ci 510e5c31af7Sopenharmony_civoid TestLog::terminateCase (qpTestResult result) 511e5c31af7Sopenharmony_ci{ 512e5c31af7Sopenharmony_ci if (m_logSupressed) return; 513e5c31af7Sopenharmony_ci if (qpTestLog_terminateCase(m_log, result) == DE_FALSE) 514e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 515e5c31af7Sopenharmony_ci} 516e5c31af7Sopenharmony_ci 517e5c31af7Sopenharmony_civoid TestLog::startTestsCasesTime (void) 518e5c31af7Sopenharmony_ci{ 519e5c31af7Sopenharmony_ci if (m_logSupressed) return; 520e5c31af7Sopenharmony_ci if (qpTestLog_startTestsCasesTime(m_log) == DE_FALSE) 521e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 522e5c31af7Sopenharmony_ci} 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_civoid TestLog::endTestsCasesTime (void) 525e5c31af7Sopenharmony_ci{ 526e5c31af7Sopenharmony_ci if (m_logSupressed) return; 527e5c31af7Sopenharmony_ci if (qpTestLog_endTestsCasesTime(m_log) == DE_FALSE) 528e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 529e5c31af7Sopenharmony_ci} 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_civoid TestLog::startSampleList (const std::string& name, const std::string& description) 532e5c31af7Sopenharmony_ci{ 533e5c31af7Sopenharmony_ci if (m_logSupressed) return; 534e5c31af7Sopenharmony_ci if (qpTestLog_startSampleList(m_log, name.c_str(), description.c_str()) == DE_FALSE) 535e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 536e5c31af7Sopenharmony_ci} 537e5c31af7Sopenharmony_ci 538e5c31af7Sopenharmony_civoid TestLog::startSampleInfo (void) 539e5c31af7Sopenharmony_ci{ 540e5c31af7Sopenharmony_ci if (m_logSupressed) return; 541e5c31af7Sopenharmony_ci if (qpTestLog_startSampleInfo(m_log) == DE_FALSE) 542e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 543e5c31af7Sopenharmony_ci} 544e5c31af7Sopenharmony_ci 545e5c31af7Sopenharmony_civoid TestLog::writeValueInfo (const std::string& name, const std::string& description, const std::string& unit, qpSampleValueTag tag) 546e5c31af7Sopenharmony_ci{ 547e5c31af7Sopenharmony_ci if (m_logSupressed) return; 548e5c31af7Sopenharmony_ci if (qpTestLog_writeValueInfo(m_log, name.c_str(), description.c_str(), unit.empty() ? DE_NULL : unit.c_str(), tag) == DE_FALSE) 549e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 550e5c31af7Sopenharmony_ci} 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_civoid TestLog::endSampleInfo (void) 553e5c31af7Sopenharmony_ci{ 554e5c31af7Sopenharmony_ci if (m_logSupressed) return; 555e5c31af7Sopenharmony_ci if (qpTestLog_endSampleInfo(m_log) == DE_FALSE) 556e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 557e5c31af7Sopenharmony_ci} 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_civoid TestLog::startSample (void) 560e5c31af7Sopenharmony_ci{ 561e5c31af7Sopenharmony_ci if (m_logSupressed) return; 562e5c31af7Sopenharmony_ci if (qpTestLog_startSample(m_log) == DE_FALSE) 563e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 564e5c31af7Sopenharmony_ci} 565e5c31af7Sopenharmony_ci 566e5c31af7Sopenharmony_civoid TestLog::writeSampleValue (double value) 567e5c31af7Sopenharmony_ci{ 568e5c31af7Sopenharmony_ci if (m_logSupressed) return; 569e5c31af7Sopenharmony_ci if (qpTestLog_writeValueFloat(m_log, value) == DE_FALSE) 570e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 571e5c31af7Sopenharmony_ci} 572e5c31af7Sopenharmony_ci 573e5c31af7Sopenharmony_civoid TestLog::writeSampleValue (deInt64 value) 574e5c31af7Sopenharmony_ci{ 575e5c31af7Sopenharmony_ci if (m_logSupressed) return; 576e5c31af7Sopenharmony_ci if (qpTestLog_writeValueInteger(m_log, value) == DE_FALSE) 577e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 578e5c31af7Sopenharmony_ci} 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_civoid TestLog::endSample (void) 581e5c31af7Sopenharmony_ci{ 582e5c31af7Sopenharmony_ci if (m_logSupressed) return; 583e5c31af7Sopenharmony_ci if (qpTestLog_endSample(m_log) == DE_FALSE) 584e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 585e5c31af7Sopenharmony_ci} 586e5c31af7Sopenharmony_ci 587e5c31af7Sopenharmony_civoid TestLog::endSampleList (void) 588e5c31af7Sopenharmony_ci{ 589e5c31af7Sopenharmony_ci if (m_logSupressed) return; 590e5c31af7Sopenharmony_ci if (qpTestLog_endSampleList(m_log) == DE_FALSE) 591e5c31af7Sopenharmony_ci throw LogWriteFailedError(); 592e5c31af7Sopenharmony_ci} 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_civoid TestLog::writeRaw(const char* rawContents) 595e5c31af7Sopenharmony_ci{ 596e5c31af7Sopenharmony_ci if (m_logSupressed) return; 597e5c31af7Sopenharmony_ci qpTestLog_writeRaw(m_log, rawContents); 598e5c31af7Sopenharmony_ci} 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_cibool TestLog::isShaderLoggingEnabled (void) 601e5c31af7Sopenharmony_ci{ 602e5c31af7Sopenharmony_ci return (qpTestLog_getLogFlags(m_log) & QP_TEST_LOG_EXCLUDE_SHADER_SOURCES) == 0; 603e5c31af7Sopenharmony_ci} 604e5c31af7Sopenharmony_ci 605e5c31af7Sopenharmony_civoid TestLog::supressLogging (bool value) 606e5c31af7Sopenharmony_ci{ 607e5c31af7Sopenharmony_ci m_logSupressed = value; 608e5c31af7Sopenharmony_ci} 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_cibool TestLog::isSupressLogging (void) 611e5c31af7Sopenharmony_ci{ 612e5c31af7Sopenharmony_ci return m_logSupressed; 613e5c31af7Sopenharmony_ci} 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ciconst TestLog::BeginMessageToken TestLog::Message = TestLog::BeginMessageToken(); 616e5c31af7Sopenharmony_ciconst TestLog::EndMessageToken TestLog::EndMessage = TestLog::EndMessageToken(); 617e5c31af7Sopenharmony_ciconst TestLog::EndImageSetToken TestLog::EndImageSet = TestLog::EndImageSetToken(); 618e5c31af7Sopenharmony_ciconst TestLog::EndSectionToken TestLog::EndSection = TestLog::EndSectionToken(); 619e5c31af7Sopenharmony_ciconst TestLog::EndShaderProgramToken TestLog::EndShaderProgram = TestLog::EndShaderProgramToken(); 620e5c31af7Sopenharmony_ciconst TestLog::SampleInfoToken TestLog::SampleInfo = TestLog::SampleInfoToken(); 621e5c31af7Sopenharmony_ciconst TestLog::EndSampleInfoToken TestLog::EndSampleInfo = TestLog::EndSampleInfoToken(); 622e5c31af7Sopenharmony_ciconst TestLog::BeginSampleToken TestLog::Sample = TestLog::BeginSampleToken(); 623e5c31af7Sopenharmony_ciconst TestLog::EndSampleToken TestLog::EndSample = TestLog::EndSampleToken(); 624e5c31af7Sopenharmony_ciconst TestLog::EndSampleListToken TestLog::EndSampleList = TestLog::EndSampleListToken(); 625e5c31af7Sopenharmony_ci 626e5c31af7Sopenharmony_ci} // tcu 627