1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) Module 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 Buffer test utilities. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "glsBufferTestUtil.hpp" 25e5c31af7Sopenharmony_ci#include "tcuRandomValueIterator.hpp" 26e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 27e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 28e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 29e5c31af7Sopenharmony_ci#include "tcuFormatUtil.hpp" 30e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 31e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 32e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 33e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 34e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 35e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 36e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 37e5c31af7Sopenharmony_ci#include "deMemory.h" 38e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 39e5c31af7Sopenharmony_ci#include "deArrayUtil.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#include <algorithm> 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 44e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_cinamespace deqp 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_cinamespace gls 49e5c31af7Sopenharmony_ci{ 50e5c31af7Sopenharmony_cinamespace BufferTestUtil 51e5c31af7Sopenharmony_ci{ 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_cienum 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_ci VERIFY_QUAD_SIZE = 8, //!< Quad size in VertexArrayVerifier 56e5c31af7Sopenharmony_ci MAX_LINES_PER_INDEX_ARRAY_DRAW = 128, //!< Maximum number of lines per one draw in IndexArrayVerifier 57e5c31af7Sopenharmony_ci INDEX_ARRAY_DRAW_VIEWPORT_WIDTH = 128, 58e5c31af7Sopenharmony_ci INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT = 128 59e5c31af7Sopenharmony_ci}; 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ciusing tcu::TestLog; 62e5c31af7Sopenharmony_ciusing std::vector; 63e5c31af7Sopenharmony_ciusing std::string; 64e5c31af7Sopenharmony_ciusing std::set; 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_ci// Helper functions. 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_civoid fillWithRandomBytes (deUint8* ptr, int numBytes, deUint32 seed) 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci std::copy(tcu::RandomValueIterator<deUint8>::begin(seed, numBytes), tcu::RandomValueIterator<deUint8>::end(), ptr); 71e5c31af7Sopenharmony_ci} 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_cibool compareByteArrays (tcu::TestLog& log, const deUint8* resPtr, const deUint8* refPtr, int numBytes) 74e5c31af7Sopenharmony_ci{ 75e5c31af7Sopenharmony_ci bool isOk = true; 76e5c31af7Sopenharmony_ci const int maxSpanLen = 8; 77e5c31af7Sopenharmony_ci const int maxDiffSpans = 4; 78e5c31af7Sopenharmony_ci int numDiffSpans = 0; 79e5c31af7Sopenharmony_ci int diffSpanStart = -1; 80e5c31af7Sopenharmony_ci int ndx = 0; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci log << TestLog::Section("Verify", "Verification result"); 83e5c31af7Sopenharmony_ci 84e5c31af7Sopenharmony_ci for (;ndx < numBytes; ndx++) 85e5c31af7Sopenharmony_ci { 86e5c31af7Sopenharmony_ci if (resPtr[ndx] != refPtr[ndx]) 87e5c31af7Sopenharmony_ci { 88e5c31af7Sopenharmony_ci if (diffSpanStart < 0) 89e5c31af7Sopenharmony_ci diffSpanStart = ndx; 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci isOk = false; 92e5c31af7Sopenharmony_ci } 93e5c31af7Sopenharmony_ci else if (diffSpanStart >= 0) 94e5c31af7Sopenharmony_ci { 95e5c31af7Sopenharmony_ci if (numDiffSpans < maxDiffSpans) 96e5c31af7Sopenharmony_ci { 97e5c31af7Sopenharmony_ci int len = ndx-diffSpanStart; 98e5c31af7Sopenharmony_ci int printLen = de::min(len, maxSpanLen); 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n" 101e5c31af7Sopenharmony_ci << " expected " << tcu::formatArray(tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart+printLen)) << "\n" 102e5c31af7Sopenharmony_ci << " got " << tcu::formatArray(tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart+printLen)) 103e5c31af7Sopenharmony_ci << TestLog::EndMessage; 104e5c31af7Sopenharmony_ci } 105e5c31af7Sopenharmony_ci else 106e5c31af7Sopenharmony_ci log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage; 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ci numDiffSpans += 1; 109e5c31af7Sopenharmony_ci diffSpanStart = -1; 110e5c31af7Sopenharmony_ci } 111e5c31af7Sopenharmony_ci } 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci if (diffSpanStart >= 0) 114e5c31af7Sopenharmony_ci { 115e5c31af7Sopenharmony_ci if (numDiffSpans < maxDiffSpans) 116e5c31af7Sopenharmony_ci { 117e5c31af7Sopenharmony_ci int len = ndx-diffSpanStart; 118e5c31af7Sopenharmony_ci int printLen = de::min(len, maxSpanLen); 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n" 121e5c31af7Sopenharmony_ci << " expected " << tcu::formatArray(tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart+printLen)) << "\n" 122e5c31af7Sopenharmony_ci << " got " << tcu::formatArray(tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart+printLen)) 123e5c31af7Sopenharmony_ci << TestLog::EndMessage; 124e5c31af7Sopenharmony_ci } 125e5c31af7Sopenharmony_ci else 126e5c31af7Sopenharmony_ci log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage; 127e5c31af7Sopenharmony_ci } 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ci log << TestLog::Message << (isOk ? "Verification passed." : "Verification FAILED!") << TestLog::EndMessage; 130e5c31af7Sopenharmony_ci log << TestLog::EndSection; 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci return isOk; 133e5c31af7Sopenharmony_ci} 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_ciconst char* getBufferTargetName (deUint32 target) 136e5c31af7Sopenharmony_ci{ 137e5c31af7Sopenharmony_ci switch (target) 138e5c31af7Sopenharmony_ci { 139e5c31af7Sopenharmony_ci case GL_ARRAY_BUFFER: return "array"; 140e5c31af7Sopenharmony_ci case GL_COPY_READ_BUFFER: return "copy_read"; 141e5c31af7Sopenharmony_ci case GL_COPY_WRITE_BUFFER: return "copy_write"; 142e5c31af7Sopenharmony_ci case GL_ELEMENT_ARRAY_BUFFER: return "element_array"; 143e5c31af7Sopenharmony_ci case GL_PIXEL_PACK_BUFFER: return "pixel_pack"; 144e5c31af7Sopenharmony_ci case GL_PIXEL_UNPACK_BUFFER: return "pixel_unpack"; 145e5c31af7Sopenharmony_ci case GL_TEXTURE_BUFFER: return "texture"; 146e5c31af7Sopenharmony_ci case GL_TRANSFORM_FEEDBACK_BUFFER: return "transform_feedback"; 147e5c31af7Sopenharmony_ci case GL_UNIFORM_BUFFER: return "uniform"; 148e5c31af7Sopenharmony_ci default: 149e5c31af7Sopenharmony_ci DE_ASSERT(false); 150e5c31af7Sopenharmony_ci return DE_NULL; 151e5c31af7Sopenharmony_ci } 152e5c31af7Sopenharmony_ci} 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ciconst char* getUsageHintName (deUint32 hint) 155e5c31af7Sopenharmony_ci{ 156e5c31af7Sopenharmony_ci switch (hint) 157e5c31af7Sopenharmony_ci { 158e5c31af7Sopenharmony_ci case GL_STREAM_DRAW: return "stream_draw"; 159e5c31af7Sopenharmony_ci case GL_STREAM_READ: return "stream_read"; 160e5c31af7Sopenharmony_ci case GL_STREAM_COPY: return "stream_copy"; 161e5c31af7Sopenharmony_ci case GL_STATIC_DRAW: return "static_draw"; 162e5c31af7Sopenharmony_ci case GL_STATIC_READ: return "static_read"; 163e5c31af7Sopenharmony_ci case GL_STATIC_COPY: return "static_copy"; 164e5c31af7Sopenharmony_ci case GL_DYNAMIC_DRAW: return "dynamic_draw"; 165e5c31af7Sopenharmony_ci case GL_DYNAMIC_READ: return "dynamic_read"; 166e5c31af7Sopenharmony_ci case GL_DYNAMIC_COPY: return "dynamic_copy"; 167e5c31af7Sopenharmony_ci default: 168e5c31af7Sopenharmony_ci DE_ASSERT(false); 169e5c31af7Sopenharmony_ci return DE_NULL; 170e5c31af7Sopenharmony_ci } 171e5c31af7Sopenharmony_ci} 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci// BufferCase 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ciBufferCase::BufferCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description) 176e5c31af7Sopenharmony_ci : TestCase (testCtx, name, description) 177e5c31af7Sopenharmony_ci , CallLogWrapper (renderCtx.getFunctions(), testCtx.getLog()) 178e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 179e5c31af7Sopenharmony_ci{ 180e5c31af7Sopenharmony_ci} 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ciBufferCase::~BufferCase (void) 183e5c31af7Sopenharmony_ci{ 184e5c31af7Sopenharmony_ci enableLogging(false); 185e5c31af7Sopenharmony_ci BufferCase::deinit(); 186e5c31af7Sopenharmony_ci} 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_civoid BufferCase::init (void) 189e5c31af7Sopenharmony_ci{ 190e5c31af7Sopenharmony_ci enableLogging(true); 191e5c31af7Sopenharmony_ci} 192e5c31af7Sopenharmony_ci 193e5c31af7Sopenharmony_civoid BufferCase::deinit (void) 194e5c31af7Sopenharmony_ci{ 195e5c31af7Sopenharmony_ci for (set<deUint32>::const_iterator bufIter = m_allocatedBuffers.begin(); bufIter != m_allocatedBuffers.end(); bufIter++) 196e5c31af7Sopenharmony_ci glDeleteBuffers(1, &(*bufIter)); 197e5c31af7Sopenharmony_ci} 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_cideUint32 BufferCase::genBuffer (void) 200e5c31af7Sopenharmony_ci{ 201e5c31af7Sopenharmony_ci deUint32 buf = 0; 202e5c31af7Sopenharmony_ci glGenBuffers(1, &buf); 203e5c31af7Sopenharmony_ci if (buf != 0) 204e5c31af7Sopenharmony_ci { 205e5c31af7Sopenharmony_ci try 206e5c31af7Sopenharmony_ci { 207e5c31af7Sopenharmony_ci m_allocatedBuffers.insert(buf); 208e5c31af7Sopenharmony_ci } 209e5c31af7Sopenharmony_ci catch (const std::exception&) 210e5c31af7Sopenharmony_ci { 211e5c31af7Sopenharmony_ci glDeleteBuffers(1, &buf); 212e5c31af7Sopenharmony_ci throw; 213e5c31af7Sopenharmony_ci } 214e5c31af7Sopenharmony_ci } 215e5c31af7Sopenharmony_ci return buf; 216e5c31af7Sopenharmony_ci} 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_civoid BufferCase::deleteBuffer (deUint32 buffer) 219e5c31af7Sopenharmony_ci{ 220e5c31af7Sopenharmony_ci glDeleteBuffers(1, &buffer); 221e5c31af7Sopenharmony_ci m_allocatedBuffers.erase(buffer); 222e5c31af7Sopenharmony_ci} 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_civoid BufferCase::checkError (void) 225e5c31af7Sopenharmony_ci{ 226e5c31af7Sopenharmony_ci glw::GLenum err = glGetError(); 227e5c31af7Sopenharmony_ci if (err != GL_NO_ERROR) 228e5c31af7Sopenharmony_ci throw tcu::TestError(string("Got ") + glu::getErrorStr(err).toString()); 229e5c31af7Sopenharmony_ci} 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci// ReferenceBuffer 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_civoid ReferenceBuffer::setSize (int numBytes) 234e5c31af7Sopenharmony_ci{ 235e5c31af7Sopenharmony_ci m_data.resize(numBytes); 236e5c31af7Sopenharmony_ci} 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_civoid ReferenceBuffer::setData (int numBytes, const deUint8* bytes) 239e5c31af7Sopenharmony_ci{ 240e5c31af7Sopenharmony_ci m_data.resize(numBytes); 241e5c31af7Sopenharmony_ci std::copy(bytes, bytes+numBytes, m_data.begin()); 242e5c31af7Sopenharmony_ci} 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_civoid ReferenceBuffer::setSubData (int offset, int numBytes, const deUint8* bytes) 245e5c31af7Sopenharmony_ci{ 246e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(offset, 0, (int)m_data.size()) && de::inRange(offset+numBytes, offset, (int)m_data.size())); 247e5c31af7Sopenharmony_ci std::copy(bytes, bytes+numBytes, m_data.begin()+offset); 248e5c31af7Sopenharmony_ci} 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci// BufferWriterBase 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ciBufferWriterBase::BufferWriterBase (glu::RenderContext& renderCtx, tcu::TestLog& log) 253e5c31af7Sopenharmony_ci : CallLogWrapper (renderCtx.getFunctions(), log) 254e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 255e5c31af7Sopenharmony_ci{ 256e5c31af7Sopenharmony_ci enableLogging(true); 257e5c31af7Sopenharmony_ci} 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_civoid BufferWriterBase::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 targetHint) 260e5c31af7Sopenharmony_ci{ 261e5c31af7Sopenharmony_ci DE_UNREF(targetHint); 262e5c31af7Sopenharmony_ci write(buffer, offset, numBytes, bytes); 263e5c31af7Sopenharmony_ci} 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_ci// BufferWriter 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ciBufferWriter::BufferWriter (glu::RenderContext& renderCtx, tcu::TestLog& log, WriteType writeType) 268e5c31af7Sopenharmony_ci : m_writer(DE_NULL) 269e5c31af7Sopenharmony_ci{ 270e5c31af7Sopenharmony_ci switch (writeType) 271e5c31af7Sopenharmony_ci { 272e5c31af7Sopenharmony_ci case WRITE_BUFFER_SUB_DATA: m_writer = new BufferSubDataWriter (renderCtx, log); break; 273e5c31af7Sopenharmony_ci case WRITE_BUFFER_WRITE_MAP: m_writer = new BufferWriteMapWriter (renderCtx, log); break; 274e5c31af7Sopenharmony_ci default: 275e5c31af7Sopenharmony_ci TCU_FAIL("Unsupported writer"); 276e5c31af7Sopenharmony_ci } 277e5c31af7Sopenharmony_ci} 278e5c31af7Sopenharmony_ci 279e5c31af7Sopenharmony_ciBufferWriter::~BufferWriter (void) 280e5c31af7Sopenharmony_ci{ 281e5c31af7Sopenharmony_ci delete m_writer; 282e5c31af7Sopenharmony_ci} 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_civoid BufferWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes) 285e5c31af7Sopenharmony_ci{ 286e5c31af7Sopenharmony_ci DE_ASSERT(numBytes >= getMinSize()); 287e5c31af7Sopenharmony_ci DE_ASSERT(offset%getAlignment() == 0); 288e5c31af7Sopenharmony_ci DE_ASSERT((offset+numBytes)%getAlignment() == 0); 289e5c31af7Sopenharmony_ci return m_writer->write(buffer, offset, numBytes, bytes); 290e5c31af7Sopenharmony_ci} 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_civoid BufferWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 targetHint) 293e5c31af7Sopenharmony_ci{ 294e5c31af7Sopenharmony_ci DE_ASSERT(numBytes >= getMinSize()); 295e5c31af7Sopenharmony_ci DE_ASSERT(offset%getAlignment() == 0); 296e5c31af7Sopenharmony_ci DE_ASSERT((offset+numBytes)%getAlignment() == 0); 297e5c31af7Sopenharmony_ci return m_writer->write(buffer, offset, numBytes, bytes, targetHint); 298e5c31af7Sopenharmony_ci} 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci// BufferSubDataWriter 301e5c31af7Sopenharmony_ci 302e5c31af7Sopenharmony_civoid BufferSubDataWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes) 303e5c31af7Sopenharmony_ci{ 304e5c31af7Sopenharmony_ci write(buffer, offset, numBytes, bytes, GL_ARRAY_BUFFER); 305e5c31af7Sopenharmony_ci} 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_civoid BufferSubDataWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 target) 308e5c31af7Sopenharmony_ci{ 309e5c31af7Sopenharmony_ci glBindBuffer(target, buffer); 310e5c31af7Sopenharmony_ci glBufferSubData(target, offset, numBytes, bytes); 311e5c31af7Sopenharmony_ci glBindBuffer(target, 0); 312e5c31af7Sopenharmony_ci GLU_CHECK(); 313e5c31af7Sopenharmony_ci} 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci// BufferWriteMapWriter 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_civoid BufferWriteMapWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes) 318e5c31af7Sopenharmony_ci{ 319e5c31af7Sopenharmony_ci write(buffer, offset, numBytes, bytes, GL_ARRAY_BUFFER); 320e5c31af7Sopenharmony_ci} 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_civoid BufferWriteMapWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 target) 323e5c31af7Sopenharmony_ci{ 324e5c31af7Sopenharmony_ci glBindBuffer(target, buffer); 325e5c31af7Sopenharmony_ci 326e5c31af7Sopenharmony_ci void* ptr = glMapBufferRange(target, offset, numBytes, GL_MAP_WRITE_BIT); 327e5c31af7Sopenharmony_ci GLU_CHECK_MSG("glMapBufferRange"); 328e5c31af7Sopenharmony_ci 329e5c31af7Sopenharmony_ci deMemcpy(ptr, bytes, numBytes); 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci glUnmapBuffer(target); 332e5c31af7Sopenharmony_ci glBindBuffer(target, 0); 333e5c31af7Sopenharmony_ci GLU_CHECK(); 334e5c31af7Sopenharmony_ci} 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci// BufferVerifierBase 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ciBufferVerifierBase::BufferVerifierBase (glu::RenderContext& renderCtx, tcu::TestLog& log) 339e5c31af7Sopenharmony_ci : CallLogWrapper (renderCtx.getFunctions(), log) 340e5c31af7Sopenharmony_ci , m_renderCtx (renderCtx) 341e5c31af7Sopenharmony_ci , m_log (log) 342e5c31af7Sopenharmony_ci{ 343e5c31af7Sopenharmony_ci enableLogging(true); 344e5c31af7Sopenharmony_ci} 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_cibool BufferVerifierBase::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes, deUint32 targetHint) 347e5c31af7Sopenharmony_ci{ 348e5c31af7Sopenharmony_ci DE_UNREF(targetHint); 349e5c31af7Sopenharmony_ci return verify(buffer, reference, offset, numBytes); 350e5c31af7Sopenharmony_ci} 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci// BufferVerifier 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_ciBufferVerifier::BufferVerifier (glu::RenderContext& renderCtx, tcu::TestLog& log, VerifyType verifyType) 355e5c31af7Sopenharmony_ci : m_verifier(DE_NULL) 356e5c31af7Sopenharmony_ci{ 357e5c31af7Sopenharmony_ci switch (verifyType) 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci case VERIFY_AS_VERTEX_ARRAY: m_verifier = new VertexArrayVerifier(renderCtx, log); break; 360e5c31af7Sopenharmony_ci case VERIFY_AS_INDEX_ARRAY: m_verifier = new IndexArrayVerifier (renderCtx, log); break; 361e5c31af7Sopenharmony_ci case VERIFY_BUFFER_READ_MAP: m_verifier = new BufferMapVerifier (renderCtx, log); break; 362e5c31af7Sopenharmony_ci default: 363e5c31af7Sopenharmony_ci TCU_FAIL("Unsupported verifier"); 364e5c31af7Sopenharmony_ci } 365e5c31af7Sopenharmony_ci} 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ciBufferVerifier::~BufferVerifier (void) 368e5c31af7Sopenharmony_ci{ 369e5c31af7Sopenharmony_ci delete m_verifier; 370e5c31af7Sopenharmony_ci} 371e5c31af7Sopenharmony_ci 372e5c31af7Sopenharmony_cibool BufferVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes) 373e5c31af7Sopenharmony_ci{ 374e5c31af7Sopenharmony_ci DE_ASSERT(numBytes >= getMinSize()); 375e5c31af7Sopenharmony_ci DE_ASSERT(offset%getAlignment() == 0); 376e5c31af7Sopenharmony_ci DE_ASSERT((offset+numBytes)%getAlignment() == 0); 377e5c31af7Sopenharmony_ci return m_verifier->verify(buffer, reference, offset, numBytes); 378e5c31af7Sopenharmony_ci} 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_cibool BufferVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes, deUint32 targetHint) 381e5c31af7Sopenharmony_ci{ 382e5c31af7Sopenharmony_ci DE_ASSERT(numBytes >= getMinSize()); 383e5c31af7Sopenharmony_ci DE_ASSERT(offset%getAlignment() == 0); 384e5c31af7Sopenharmony_ci DE_ASSERT((offset+numBytes)%getAlignment() == 0); 385e5c31af7Sopenharmony_ci return m_verifier->verify(buffer, reference, offset, numBytes, targetHint); 386e5c31af7Sopenharmony_ci} 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci// BufferMapVerifier 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_cibool BufferMapVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes) 391e5c31af7Sopenharmony_ci{ 392e5c31af7Sopenharmony_ci return verify(buffer, reference, offset, numBytes, GL_ARRAY_BUFFER); 393e5c31af7Sopenharmony_ci} 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_cibool BufferMapVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes, deUint32 target) 396e5c31af7Sopenharmony_ci{ 397e5c31af7Sopenharmony_ci const deUint8* mapPtr = DE_NULL; 398e5c31af7Sopenharmony_ci bool isOk = false; 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci glBindBuffer(target, buffer); 401e5c31af7Sopenharmony_ci mapPtr = (const deUint8*)glMapBufferRange(target, offset, numBytes, GL_MAP_READ_BIT); 402e5c31af7Sopenharmony_ci GLU_CHECK_MSG("glMapBufferRange"); 403e5c31af7Sopenharmony_ci TCU_CHECK(mapPtr); 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ci isOk = compareByteArrays(m_log, mapPtr, reference+offset, numBytes); 406e5c31af7Sopenharmony_ci 407e5c31af7Sopenharmony_ci glUnmapBuffer(target); 408e5c31af7Sopenharmony_ci GLU_CHECK_MSG("glUnmapBuffer"); 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci glBindBuffer(target, 0); 411e5c31af7Sopenharmony_ci 412e5c31af7Sopenharmony_ci return isOk; 413e5c31af7Sopenharmony_ci} 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci// VertexArrayVerifier 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ciVertexArrayVerifier::VertexArrayVerifier (glu::RenderContext& renderCtx, tcu::TestLog& log) 418e5c31af7Sopenharmony_ci : BufferVerifierBase (renderCtx, log) 419e5c31af7Sopenharmony_ci , m_program (DE_NULL) 420e5c31af7Sopenharmony_ci , m_posLoc (0) 421e5c31af7Sopenharmony_ci , m_byteVecLoc (0) 422e5c31af7Sopenharmony_ci , m_vao (0) 423e5c31af7Sopenharmony_ci{ 424e5c31af7Sopenharmony_ci const glu::ContextType ctxType = renderCtx.getType(); 425e5c31af7Sopenharmony_ci const glu::GLSLVersion glslVersion = glu::isContextTypeES(ctxType) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330; 426e5c31af7Sopenharmony_ci 427e5c31af7Sopenharmony_ci DE_ASSERT(glu::isGLSLVersionSupported(ctxType, glslVersion)); 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources( 430e5c31af7Sopenharmony_ci string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n" 431e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 432e5c31af7Sopenharmony_ci "in mediump vec3 a_byteVec;\n" 433e5c31af7Sopenharmony_ci "out mediump vec3 v_byteVec;\n" 434e5c31af7Sopenharmony_ci "void main (void)\n" 435e5c31af7Sopenharmony_ci "{\n" 436e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 437e5c31af7Sopenharmony_ci " v_byteVec = a_byteVec;\n" 438e5c31af7Sopenharmony_ci "}\n", 439e5c31af7Sopenharmony_ci 440e5c31af7Sopenharmony_ci string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n" 441e5c31af7Sopenharmony_ci "in mediump vec3 v_byteVec;\n" 442e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 443e5c31af7Sopenharmony_ci "void main (void)\n" 444e5c31af7Sopenharmony_ci "{\n" 445e5c31af7Sopenharmony_ci " o_color = vec4(v_byteVec, 1.0);\n" 446e5c31af7Sopenharmony_ci "}\n")); 447e5c31af7Sopenharmony_ci 448e5c31af7Sopenharmony_ci if (!m_program->isOk()) 449e5c31af7Sopenharmony_ci { 450e5c31af7Sopenharmony_ci m_log << *m_program; 451e5c31af7Sopenharmony_ci delete m_program; 452e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 453e5c31af7Sopenharmony_ci } 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 456e5c31af7Sopenharmony_ci m_posLoc = gl.getAttribLocation(m_program->getProgram(), "a_position"); 457e5c31af7Sopenharmony_ci m_byteVecLoc = gl.getAttribLocation(m_program->getProgram(), "a_byteVec"); 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao); 460e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_positionBuf); 461e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_indexBuf); 462e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Initialization failed"); 463e5c31af7Sopenharmony_ci} 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ciVertexArrayVerifier::~VertexArrayVerifier (void) 466e5c31af7Sopenharmony_ci{ 467e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_ci if (m_vao) gl.deleteVertexArrays(1, &m_vao); 470e5c31af7Sopenharmony_ci if (m_positionBuf) gl.deleteBuffers(1, &m_positionBuf); 471e5c31af7Sopenharmony_ci if (m_indexBuf) gl.deleteBuffers(1, &m_indexBuf); 472e5c31af7Sopenharmony_ci 473e5c31af7Sopenharmony_ci delete m_program; 474e5c31af7Sopenharmony_ci} 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_cistatic void computePositions (vector<tcu::Vec2>& positions, int gridSizeX, int gridSizeY) 477e5c31af7Sopenharmony_ci{ 478e5c31af7Sopenharmony_ci positions.resize(gridSizeX*gridSizeY*4); 479e5c31af7Sopenharmony_ci 480e5c31af7Sopenharmony_ci for (int y = 0; y < gridSizeY; y++) 481e5c31af7Sopenharmony_ci for (int x = 0; x < gridSizeX; x++) 482e5c31af7Sopenharmony_ci { 483e5c31af7Sopenharmony_ci float sx0 = (float)(x+0) / (float)gridSizeX; 484e5c31af7Sopenharmony_ci float sy0 = (float)(y+0) / (float)gridSizeY; 485e5c31af7Sopenharmony_ci float sx1 = (float)(x+1) / (float)gridSizeX; 486e5c31af7Sopenharmony_ci float sy1 = (float)(y+1) / (float)gridSizeY; 487e5c31af7Sopenharmony_ci float fx0 = 2.0f * sx0 - 1.0f; 488e5c31af7Sopenharmony_ci float fy0 = 2.0f * sy0 - 1.0f; 489e5c31af7Sopenharmony_ci float fx1 = 2.0f * sx1 - 1.0f; 490e5c31af7Sopenharmony_ci float fy1 = 2.0f * sy1 - 1.0f; 491e5c31af7Sopenharmony_ci int baseNdx = (y * gridSizeX + x)*4; 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci positions[baseNdx+0] = tcu::Vec2(fx0, fy0); 494e5c31af7Sopenharmony_ci positions[baseNdx+1] = tcu::Vec2(fx0, fy1); 495e5c31af7Sopenharmony_ci positions[baseNdx+2] = tcu::Vec2(fx1, fy0); 496e5c31af7Sopenharmony_ci positions[baseNdx+3] = tcu::Vec2(fx1, fy1); 497e5c31af7Sopenharmony_ci } 498e5c31af7Sopenharmony_ci} 499e5c31af7Sopenharmony_ci 500e5c31af7Sopenharmony_cistatic void computeIndices (vector<deUint16>& indices, int gridSizeX, int gridSizeY) 501e5c31af7Sopenharmony_ci{ 502e5c31af7Sopenharmony_ci indices.resize(3 * 2 * gridSizeX * gridSizeY); 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_ci for (int quadNdx = 0; quadNdx < gridSizeX*gridSizeY; quadNdx++) 505e5c31af7Sopenharmony_ci { 506e5c31af7Sopenharmony_ci int v00 = quadNdx*4 + 0; 507e5c31af7Sopenharmony_ci int v01 = quadNdx*4 + 1; 508e5c31af7Sopenharmony_ci int v10 = quadNdx*4 + 2; 509e5c31af7Sopenharmony_ci int v11 = quadNdx*4 + 3; 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci DE_ASSERT(v11 < (1<<16)); 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci indices[quadNdx*6 + 0] = (deUint16)v10; 514e5c31af7Sopenharmony_ci indices[quadNdx*6 + 1] = (deUint16)v00; 515e5c31af7Sopenharmony_ci indices[quadNdx*6 + 2] = (deUint16)v01; 516e5c31af7Sopenharmony_ci 517e5c31af7Sopenharmony_ci indices[quadNdx*6 + 3] = (deUint16)v10; 518e5c31af7Sopenharmony_ci indices[quadNdx*6 + 4] = (deUint16)v01; 519e5c31af7Sopenharmony_ci indices[quadNdx*6 + 5] = (deUint16)v11; 520e5c31af7Sopenharmony_ci } 521e5c31af7Sopenharmony_ci} 522e5c31af7Sopenharmony_ci 523e5c31af7Sopenharmony_cistatic inline tcu::Vec4 fetchVtxColor (const deUint8* ptr, int vtxNdx) 524e5c31af7Sopenharmony_ci{ 525e5c31af7Sopenharmony_ci return tcu::RGBA(*(ptr + vtxNdx*3 + 0), 526e5c31af7Sopenharmony_ci *(ptr + vtxNdx*3 + 1), 527e5c31af7Sopenharmony_ci *(ptr + vtxNdx*3 + 2), 528e5c31af7Sopenharmony_ci 255).toVec(); 529e5c31af7Sopenharmony_ci} 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_cistatic void renderQuadGridReference (tcu::Surface& dst, int numQuads, int rowLength, const deUint8* inPtr) 532e5c31af7Sopenharmony_ci{ 533e5c31af7Sopenharmony_ci using tcu::Vec4; 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci dst.setSize(rowLength*VERIFY_QUAD_SIZE, (numQuads/rowLength + (numQuads%rowLength != 0 ? 1 : 0))*VERIFY_QUAD_SIZE); 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_ci tcu::PixelBufferAccess dstAccess = dst.getAccess(); 538e5c31af7Sopenharmony_ci tcu::clear(dstAccess, tcu::IVec4(0, 0, 0, 0xff)); 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_ci for (int quadNdx = 0; quadNdx < numQuads; quadNdx++) 541e5c31af7Sopenharmony_ci { 542e5c31af7Sopenharmony_ci int x0 = (quadNdx%rowLength)*VERIFY_QUAD_SIZE; 543e5c31af7Sopenharmony_ci int y0 = (quadNdx/rowLength)*VERIFY_QUAD_SIZE; 544e5c31af7Sopenharmony_ci Vec4 v00 = fetchVtxColor(inPtr, quadNdx*4 + 0); 545e5c31af7Sopenharmony_ci Vec4 v10 = fetchVtxColor(inPtr, quadNdx*4 + 1); 546e5c31af7Sopenharmony_ci Vec4 v01 = fetchVtxColor(inPtr, quadNdx*4 + 2); 547e5c31af7Sopenharmony_ci Vec4 v11 = fetchVtxColor(inPtr, quadNdx*4 + 3); 548e5c31af7Sopenharmony_ci 549e5c31af7Sopenharmony_ci for (int y = 0; y < VERIFY_QUAD_SIZE; y++) 550e5c31af7Sopenharmony_ci for (int x = 0; x < VERIFY_QUAD_SIZE; x++) 551e5c31af7Sopenharmony_ci { 552e5c31af7Sopenharmony_ci float fx = ((float)x+0.5f) / (float)VERIFY_QUAD_SIZE; 553e5c31af7Sopenharmony_ci float fy = ((float)y+0.5f) / (float)VERIFY_QUAD_SIZE; 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci bool tri = fx + fy <= 1.0f; 556e5c31af7Sopenharmony_ci float tx = tri ? fx : (1.0f-fx); 557e5c31af7Sopenharmony_ci float ty = tri ? fy : (1.0f-fy); 558e5c31af7Sopenharmony_ci const Vec4& t0 = tri ? v00 : v11; 559e5c31af7Sopenharmony_ci const Vec4& t1 = tri ? v01 : v10; 560e5c31af7Sopenharmony_ci const Vec4& t2 = tri ? v10 : v01; 561e5c31af7Sopenharmony_ci Vec4 color = t0 + (t1-t0)*tx + (t2-t0)*ty; 562e5c31af7Sopenharmony_ci 563e5c31af7Sopenharmony_ci dstAccess.setPixel(color, x0+x, y0+y); 564e5c31af7Sopenharmony_ci } 565e5c31af7Sopenharmony_ci } 566e5c31af7Sopenharmony_ci} 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_cibool VertexArrayVerifier::verify (deUint32 buffer, const deUint8* refPtr, int offset, int numBytes) 569e5c31af7Sopenharmony_ci{ 570e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_renderCtx.getRenderTarget(); 571e5c31af7Sopenharmony_ci const int numBytesInVtx = 3; 572e5c31af7Sopenharmony_ci const int numBytesInQuad = numBytesInVtx*4; 573e5c31af7Sopenharmony_ci int maxQuadsX = de::min(128, renderTarget.getWidth() / VERIFY_QUAD_SIZE); 574e5c31af7Sopenharmony_ci int maxQuadsY = de::min(128, renderTarget.getHeight() / VERIFY_QUAD_SIZE); 575e5c31af7Sopenharmony_ci int maxQuadsPerBatch = maxQuadsX*maxQuadsY; 576e5c31af7Sopenharmony_ci int numVerified = 0; 577e5c31af7Sopenharmony_ci deUint32 program = m_program->getProgram(); 578e5c31af7Sopenharmony_ci tcu::RGBA threshold = renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(3,3,3,3); 579e5c31af7Sopenharmony_ci bool isOk = true; 580e5c31af7Sopenharmony_ci 581e5c31af7Sopenharmony_ci vector<tcu::Vec2> positions; 582e5c31af7Sopenharmony_ci vector<deUint16> indices; 583e5c31af7Sopenharmony_ci 584e5c31af7Sopenharmony_ci tcu::Surface rendered; 585e5c31af7Sopenharmony_ci tcu::Surface reference; 586e5c31af7Sopenharmony_ci 587e5c31af7Sopenharmony_ci DE_ASSERT(numBytes >= numBytesInQuad); // Can't render full quad with smaller buffers. 588e5c31af7Sopenharmony_ci 589e5c31af7Sopenharmony_ci computePositions(positions, maxQuadsX, maxQuadsY); 590e5c31af7Sopenharmony_ci computeIndices(indices, maxQuadsX, maxQuadsY); 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_ci // Reset buffer bindings. 593e5c31af7Sopenharmony_ci glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci // Setup rendering state. 596e5c31af7Sopenharmony_ci glViewport (0, 0, maxQuadsX*VERIFY_QUAD_SIZE, maxQuadsY*VERIFY_QUAD_SIZE); 597e5c31af7Sopenharmony_ci glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 598e5c31af7Sopenharmony_ci glUseProgram (program); 599e5c31af7Sopenharmony_ci glBindVertexArray (m_vao); 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci // Upload positions 602e5c31af7Sopenharmony_ci glBindBuffer (GL_ARRAY_BUFFER, m_positionBuf); 603e5c31af7Sopenharmony_ci glBufferData (GL_ARRAY_BUFFER, (glw::GLsizeiptr)(positions.size()*sizeof(positions[0])), &positions[0], GL_STATIC_DRAW); 604e5c31af7Sopenharmony_ci glEnableVertexAttribArray (m_posLoc); 605e5c31af7Sopenharmony_ci glVertexAttribPointer (m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL); 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci // Upload indices 608e5c31af7Sopenharmony_ci glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, m_indexBuf); 609e5c31af7Sopenharmony_ci glBufferData (GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size()*sizeof(indices[0])), &indices[0], GL_STATIC_DRAW); 610e5c31af7Sopenharmony_ci 611e5c31af7Sopenharmony_ci glEnableVertexAttribArray (m_byteVecLoc); 612e5c31af7Sopenharmony_ci glBindBuffer (GL_ARRAY_BUFFER, buffer); 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_ci while (numVerified < numBytes) 615e5c31af7Sopenharmony_ci { 616e5c31af7Sopenharmony_ci int numRemaining = numBytes-numVerified; 617e5c31af7Sopenharmony_ci bool isLeftoverBatch = numRemaining < numBytesInQuad; 618e5c31af7Sopenharmony_ci int numBytesToVerify = isLeftoverBatch ? numBytesInQuad : de::min(maxQuadsPerBatch*numBytesInQuad, numRemaining - numRemaining%numBytesInQuad); 619e5c31af7Sopenharmony_ci int curOffset = isLeftoverBatch ? (numBytes-numBytesInQuad) : numVerified; 620e5c31af7Sopenharmony_ci int numQuads = numBytesToVerify/numBytesInQuad; 621e5c31af7Sopenharmony_ci int numCols = de::min(maxQuadsX, numQuads); 622e5c31af7Sopenharmony_ci int numRows = numQuads/maxQuadsX + (numQuads%maxQuadsX != 0 ? 1 : 0); 623e5c31af7Sopenharmony_ci string imageSetDesc = string("Bytes ") + de::toString(offset+curOffset) + " to " + de::toString(offset+curOffset+numBytesToVerify-1); 624e5c31af7Sopenharmony_ci 625e5c31af7Sopenharmony_ci DE_ASSERT(numBytesToVerify > 0 && numBytesToVerify%numBytesInQuad == 0); 626e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(curOffset, 0, numBytes)); 627e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(curOffset+numBytesToVerify, curOffset, numBytes)); 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci // Render batch. 630e5c31af7Sopenharmony_ci glClear (GL_COLOR_BUFFER_BIT); 631e5c31af7Sopenharmony_ci glVertexAttribPointer (m_byteVecLoc, 3, GL_UNSIGNED_BYTE, GL_TRUE, 0, (const glw::GLvoid*)(deUintptr)(offset + curOffset)); 632e5c31af7Sopenharmony_ci glDrawElements (GL_TRIANGLES, numQuads*6, GL_UNSIGNED_SHORT, DE_NULL); 633e5c31af7Sopenharmony_ci 634e5c31af7Sopenharmony_ci renderQuadGridReference(reference, numQuads, numCols, refPtr + offset + curOffset); 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci rendered.setSize(numCols*VERIFY_QUAD_SIZE, numRows*VERIFY_QUAD_SIZE); 637e5c31af7Sopenharmony_ci glu::readPixels(m_renderCtx, 0, 0, rendered.getAccess()); 638e5c31af7Sopenharmony_ci 639e5c31af7Sopenharmony_ci if (!tcu::pixelThresholdCompare(m_log, "RenderResult", imageSetDesc.c_str(), reference, rendered, threshold, tcu::COMPARE_LOG_RESULT)) 640e5c31af7Sopenharmony_ci { 641e5c31af7Sopenharmony_ci isOk = false; 642e5c31af7Sopenharmony_ci break; 643e5c31af7Sopenharmony_ci } 644e5c31af7Sopenharmony_ci 645e5c31af7Sopenharmony_ci numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify; 646e5c31af7Sopenharmony_ci } 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci glBindVertexArray(0); 649e5c31af7Sopenharmony_ci 650e5c31af7Sopenharmony_ci return isOk; 651e5c31af7Sopenharmony_ci} 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci// IndexArrayVerifier 654e5c31af7Sopenharmony_ci 655e5c31af7Sopenharmony_ciIndexArrayVerifier::IndexArrayVerifier (glu::RenderContext& renderCtx, tcu::TestLog& log) 656e5c31af7Sopenharmony_ci : BufferVerifierBase (renderCtx, log) 657e5c31af7Sopenharmony_ci , m_program (DE_NULL) 658e5c31af7Sopenharmony_ci , m_posLoc (0) 659e5c31af7Sopenharmony_ci , m_colorLoc (0) 660e5c31af7Sopenharmony_ci{ 661e5c31af7Sopenharmony_ci 662e5c31af7Sopenharmony_ci const glu::ContextType ctxType = renderCtx.getType(); 663e5c31af7Sopenharmony_ci const glu::GLSLVersion glslVersion = glu::isContextTypeES(ctxType) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330; 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci DE_ASSERT(glu::isGLSLVersionSupported(ctxType, glslVersion)); 666e5c31af7Sopenharmony_ci 667e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources( 668e5c31af7Sopenharmony_ci string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n" 669e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 670e5c31af7Sopenharmony_ci "in mediump vec3 a_color;\n" 671e5c31af7Sopenharmony_ci "out mediump vec3 v_color;\n" 672e5c31af7Sopenharmony_ci "void main (void)\n" 673e5c31af7Sopenharmony_ci "{\n" 674e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 675e5c31af7Sopenharmony_ci " v_color = a_color;\n" 676e5c31af7Sopenharmony_ci "}\n", 677e5c31af7Sopenharmony_ci 678e5c31af7Sopenharmony_ci string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n" 679e5c31af7Sopenharmony_ci "in mediump vec3 v_color;\n" 680e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 681e5c31af7Sopenharmony_ci "void main (void)\n" 682e5c31af7Sopenharmony_ci "{\n" 683e5c31af7Sopenharmony_ci " o_color = vec4(v_color, 1.0);\n" 684e5c31af7Sopenharmony_ci "}\n")); 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci if (!m_program->isOk()) 687e5c31af7Sopenharmony_ci { 688e5c31af7Sopenharmony_ci m_log << *m_program; 689e5c31af7Sopenharmony_ci delete m_program; 690e5c31af7Sopenharmony_ci TCU_FAIL("Compile failed"); 691e5c31af7Sopenharmony_ci } 692e5c31af7Sopenharmony_ci 693e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 694e5c31af7Sopenharmony_ci m_posLoc = gl.getAttribLocation(m_program->getProgram(), "a_position"); 695e5c31af7Sopenharmony_ci m_colorLoc = gl.getAttribLocation(m_program->getProgram(), "a_color"); 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao); 698e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_positionBuf); 699e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_colorBuf); 700e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Initialization failed"); 701e5c31af7Sopenharmony_ci} 702e5c31af7Sopenharmony_ci 703e5c31af7Sopenharmony_ciIndexArrayVerifier::~IndexArrayVerifier (void) 704e5c31af7Sopenharmony_ci{ 705e5c31af7Sopenharmony_ci const glw::Functions& gl = m_renderCtx.getFunctions(); 706e5c31af7Sopenharmony_ci 707e5c31af7Sopenharmony_ci if (m_vao) gl.deleteVertexArrays(1, &m_vao); 708e5c31af7Sopenharmony_ci if (m_positionBuf) gl.deleteBuffers(1, &m_positionBuf); 709e5c31af7Sopenharmony_ci if (m_colorBuf) gl.deleteBuffers(1, &m_colorBuf); 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ci delete m_program; 712e5c31af7Sopenharmony_ci} 713e5c31af7Sopenharmony_ci 714e5c31af7Sopenharmony_cistatic void computeIndexVerifierPositions (std::vector<tcu::Vec2>& dst) 715e5c31af7Sopenharmony_ci{ 716e5c31af7Sopenharmony_ci const int numPosX = 16; 717e5c31af7Sopenharmony_ci const int numPosY = 16; 718e5c31af7Sopenharmony_ci 719e5c31af7Sopenharmony_ci dst.resize(numPosX*numPosY); 720e5c31af7Sopenharmony_ci 721e5c31af7Sopenharmony_ci for (int y = 0; y < numPosY; y++) 722e5c31af7Sopenharmony_ci { 723e5c31af7Sopenharmony_ci for (int x = 0; x < numPosX; x++) 724e5c31af7Sopenharmony_ci { 725e5c31af7Sopenharmony_ci float xf = float(x) / float(numPosX-1); 726e5c31af7Sopenharmony_ci float yf = float(y) / float(numPosY-1); 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci dst[y*numPosX + x] = tcu::Vec2(2.0f*xf - 1.0f, 2.0f*yf - 1.0f); 729e5c31af7Sopenharmony_ci } 730e5c31af7Sopenharmony_ci } 731e5c31af7Sopenharmony_ci} 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_cistatic void computeIndexVerifierColors (std::vector<tcu::Vec3>& dst) 734e5c31af7Sopenharmony_ci{ 735e5c31af7Sopenharmony_ci const int numColors = 256; 736e5c31af7Sopenharmony_ci const float minVal = 0.1f; 737e5c31af7Sopenharmony_ci const float maxVal = 0.5f; 738e5c31af7Sopenharmony_ci de::Random rnd (0xabc231); 739e5c31af7Sopenharmony_ci 740e5c31af7Sopenharmony_ci dst.resize(numColors); 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci for (std::vector<tcu::Vec3>::iterator i = dst.begin(); i != dst.end(); ++i) 743e5c31af7Sopenharmony_ci { 744e5c31af7Sopenharmony_ci i->x() = rnd.getFloat(minVal, maxVal); 745e5c31af7Sopenharmony_ci i->y() = rnd.getFloat(minVal, maxVal); 746e5c31af7Sopenharmony_ci i->z() = rnd.getFloat(minVal, maxVal); 747e5c31af7Sopenharmony_ci } 748e5c31af7Sopenharmony_ci} 749e5c31af7Sopenharmony_ci 750e5c31af7Sopenharmony_citemplate<typename T> 751e5c31af7Sopenharmony_cistatic void execVertexFetch (T* dst, const T* src, const deUint8* indices, int numIndices) 752e5c31af7Sopenharmony_ci{ 753e5c31af7Sopenharmony_ci for (int i = 0; i < numIndices; ++i) 754e5c31af7Sopenharmony_ci dst[i] = src[indices[i]]; 755e5c31af7Sopenharmony_ci} 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_cibool IndexArrayVerifier::verify (deUint32 buffer, const deUint8* refPtr, int offset, int numBytes) 758e5c31af7Sopenharmony_ci{ 759e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_renderCtx.getRenderTarget(); 760e5c31af7Sopenharmony_ci const int viewportW = de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_WIDTH, renderTarget.getWidth()); 761e5c31af7Sopenharmony_ci const int viewportH = de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT, renderTarget.getHeight()); 762e5c31af7Sopenharmony_ci const int minBytesPerBatch = 2; 763e5c31af7Sopenharmony_ci const tcu::RGBA threshold (0,0,0,0); 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_ci std::vector<tcu::Vec2> positions; 766e5c31af7Sopenharmony_ci std::vector<tcu::Vec3> colors; 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci std::vector<tcu::Vec2> fetchedPos (MAX_LINES_PER_INDEX_ARRAY_DRAW+1); 769e5c31af7Sopenharmony_ci std::vector<tcu::Vec3> fetchedColor (MAX_LINES_PER_INDEX_ARRAY_DRAW+1); 770e5c31af7Sopenharmony_ci 771e5c31af7Sopenharmony_ci tcu::Surface indexBufferImg (viewportW, viewportH); 772e5c31af7Sopenharmony_ci tcu::Surface referenceImg (viewportW, viewportH); 773e5c31af7Sopenharmony_ci 774e5c31af7Sopenharmony_ci int numVerified = 0; 775e5c31af7Sopenharmony_ci bool isOk = true; 776e5c31af7Sopenharmony_ci 777e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(tcu::Vec2) == sizeof(float)*2); 778e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(tcu::Vec3) == sizeof(float)*3); 779e5c31af7Sopenharmony_ci 780e5c31af7Sopenharmony_ci computeIndexVerifierPositions(positions); 781e5c31af7Sopenharmony_ci computeIndexVerifierColors(colors); 782e5c31af7Sopenharmony_ci 783e5c31af7Sopenharmony_ci // Reset buffer bindings. 784e5c31af7Sopenharmony_ci glBindVertexArray (m_vao); 785e5c31af7Sopenharmony_ci glBindBuffer (GL_PIXEL_PACK_BUFFER, 0); 786e5c31af7Sopenharmony_ci glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, buffer); 787e5c31af7Sopenharmony_ci 788e5c31af7Sopenharmony_ci // Setup rendering state. 789e5c31af7Sopenharmony_ci glViewport (0, 0, viewportW, viewportH); 790e5c31af7Sopenharmony_ci glClearColor (0.0f, 0.0f, 0.0f, 1.0f); 791e5c31af7Sopenharmony_ci glUseProgram (m_program->getProgram()); 792e5c31af7Sopenharmony_ci glEnableVertexAttribArray (m_posLoc); 793e5c31af7Sopenharmony_ci glEnableVertexAttribArray (m_colorLoc); 794e5c31af7Sopenharmony_ci glEnable (GL_BLEND); 795e5c31af7Sopenharmony_ci glBlendFunc (GL_ONE, GL_ONE); 796e5c31af7Sopenharmony_ci glBlendEquation (GL_FUNC_ADD); 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci while (numVerified < numBytes) 799e5c31af7Sopenharmony_ci { 800e5c31af7Sopenharmony_ci int numRemaining = numBytes-numVerified; 801e5c31af7Sopenharmony_ci bool isLeftoverBatch = numRemaining < minBytesPerBatch; 802e5c31af7Sopenharmony_ci int numBytesToVerify = isLeftoverBatch ? minBytesPerBatch : de::min(MAX_LINES_PER_INDEX_ARRAY_DRAW+1, numRemaining); 803e5c31af7Sopenharmony_ci int curOffset = isLeftoverBatch ? (numBytes-minBytesPerBatch) : numVerified; 804e5c31af7Sopenharmony_ci string imageSetDesc = string("Bytes ") + de::toString(offset+curOffset) + " to " + de::toString(offset+curOffset+numBytesToVerify-1); 805e5c31af7Sopenharmony_ci 806e5c31af7Sopenharmony_ci // Step 1: Render using index buffer. 807e5c31af7Sopenharmony_ci glClear (GL_COLOR_BUFFER_BIT); 808e5c31af7Sopenharmony_ci 809e5c31af7Sopenharmony_ci glBindBuffer (GL_ARRAY_BUFFER, m_positionBuf); 810e5c31af7Sopenharmony_ci glBufferData (GL_ARRAY_BUFFER, (glw::GLsizeiptr)(positions.size()*sizeof(positions[0])), &positions[0], GL_STREAM_DRAW); 811e5c31af7Sopenharmony_ci glVertexAttribPointer (m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL); 812e5c31af7Sopenharmony_ci 813e5c31af7Sopenharmony_ci glBindBuffer (GL_ARRAY_BUFFER, m_colorBuf); 814e5c31af7Sopenharmony_ci glBufferData (GL_ARRAY_BUFFER, (glw::GLsizeiptr)(colors.size()*sizeof(colors[0])), &colors[0], GL_STREAM_DRAW); 815e5c31af7Sopenharmony_ci glVertexAttribPointer (m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL); 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci glDrawElements (GL_LINE_STRIP, numBytesToVerify, GL_UNSIGNED_BYTE, (void*)(deUintptr)(offset+curOffset)); 818e5c31af7Sopenharmony_ci glu::readPixels (m_renderCtx, 0, 0, indexBufferImg.getAccess()); 819e5c31af7Sopenharmony_ci 820e5c31af7Sopenharmony_ci // Step 2: Do manual fetch and render without index buffer. 821e5c31af7Sopenharmony_ci execVertexFetch(&fetchedPos[0], &positions[0], refPtr+offset+curOffset, numBytesToVerify); 822e5c31af7Sopenharmony_ci execVertexFetch(&fetchedColor[0], &colors[0], refPtr+offset+curOffset, numBytesToVerify); 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_ci glClear (GL_COLOR_BUFFER_BIT); 825e5c31af7Sopenharmony_ci 826e5c31af7Sopenharmony_ci glBindBuffer (GL_ARRAY_BUFFER, m_positionBuf); 827e5c31af7Sopenharmony_ci glBufferData (GL_ARRAY_BUFFER, (glw::GLsizeiptr)(fetchedPos.size()*sizeof(fetchedPos[0])), &fetchedPos[0], GL_STREAM_DRAW); 828e5c31af7Sopenharmony_ci glVertexAttribPointer (m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL); 829e5c31af7Sopenharmony_ci 830e5c31af7Sopenharmony_ci glBindBuffer (GL_ARRAY_BUFFER, m_colorBuf); 831e5c31af7Sopenharmony_ci glBufferData (GL_ARRAY_BUFFER, (glw::GLsizeiptr)(fetchedColor.size()*sizeof(fetchedColor[0])), &fetchedColor[0], GL_STREAM_DRAW); 832e5c31af7Sopenharmony_ci glVertexAttribPointer (m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL); 833e5c31af7Sopenharmony_ci 834e5c31af7Sopenharmony_ci glDrawArrays (GL_LINE_STRIP, 0, numBytesToVerify); 835e5c31af7Sopenharmony_ci glu::readPixels (m_renderCtx, 0, 0, referenceImg.getAccess()); 836e5c31af7Sopenharmony_ci 837e5c31af7Sopenharmony_ci if (!tcu::pixelThresholdCompare(m_log, "RenderResult", imageSetDesc.c_str(), referenceImg, indexBufferImg, threshold, tcu::COMPARE_LOG_RESULT)) 838e5c31af7Sopenharmony_ci { 839e5c31af7Sopenharmony_ci isOk = false; 840e5c31af7Sopenharmony_ci break; 841e5c31af7Sopenharmony_ci } 842e5c31af7Sopenharmony_ci 843e5c31af7Sopenharmony_ci numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify; 844e5c31af7Sopenharmony_ci } 845e5c31af7Sopenharmony_ci 846e5c31af7Sopenharmony_ci glBindVertexArray(0); 847e5c31af7Sopenharmony_ci 848e5c31af7Sopenharmony_ci return isOk; 849e5c31af7Sopenharmony_ci} 850e5c31af7Sopenharmony_ci 851e5c31af7Sopenharmony_ciconst char* getWriteTypeDescription (WriteType write) 852e5c31af7Sopenharmony_ci{ 853e5c31af7Sopenharmony_ci static const char* s_desc[] = 854e5c31af7Sopenharmony_ci { 855e5c31af7Sopenharmony_ci "glBufferSubData()", 856e5c31af7Sopenharmony_ci "glMapBufferRange()", 857e5c31af7Sopenharmony_ci "transform feedback", 858e5c31af7Sopenharmony_ci "glReadPixels() into PBO binding" 859e5c31af7Sopenharmony_ci }; 860e5c31af7Sopenharmony_ci return de::getSizedArrayElement<WRITE_LAST>(s_desc, write); 861e5c31af7Sopenharmony_ci} 862e5c31af7Sopenharmony_ci 863e5c31af7Sopenharmony_ciconst char* getVerifyTypeDescription (VerifyType verify) 864e5c31af7Sopenharmony_ci{ 865e5c31af7Sopenharmony_ci static const char* s_desc[] = 866e5c31af7Sopenharmony_ci { 867e5c31af7Sopenharmony_ci "rendering as vertex data", 868e5c31af7Sopenharmony_ci "rendering as index data", 869e5c31af7Sopenharmony_ci "reading in shader as uniform buffer data", 870e5c31af7Sopenharmony_ci "using as PBO and uploading to texture", 871e5c31af7Sopenharmony_ci "reading back using glMapBufferRange()" 872e5c31af7Sopenharmony_ci }; 873e5c31af7Sopenharmony_ci return de::getSizedArrayElement<VERIFY_LAST>(s_desc, verify); 874e5c31af7Sopenharmony_ci} 875e5c31af7Sopenharmony_ci 876e5c31af7Sopenharmony_ci} // BufferTestUtil 877e5c31af7Sopenharmony_ci} // gls 878e5c31af7Sopenharmony_ci} // deqp 879