1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.0 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 Vertex texture tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es3fVertexTextureTests.hpp" 25e5c31af7Sopenharmony_ci#include "glsTextureTestUtil.hpp" 26e5c31af7Sopenharmony_ci#include "gluTexture.hpp" 27e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 28e5c31af7Sopenharmony_ci#include "gluTextureUtil.hpp" 29e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 30e5c31af7Sopenharmony_ci#include "tcuMatrix.hpp" 31e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 32e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 33e5c31af7Sopenharmony_ci#include "deMath.h" 34e5c31af7Sopenharmony_ci#include "deRandom.hpp" 35e5c31af7Sopenharmony_ci#include "deString.h" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci#include <string> 38e5c31af7Sopenharmony_ci#include <vector> 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include <limits> 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ci#include "glw.h" 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ciusing tcu::TestLog; 45e5c31af7Sopenharmony_ciusing tcu::Vec2; 46e5c31af7Sopenharmony_ciusing tcu::Vec3; 47e5c31af7Sopenharmony_ciusing tcu::Vec4; 48e5c31af7Sopenharmony_ciusing tcu::IVec2; 49e5c31af7Sopenharmony_ciusing tcu::IVec3; 50e5c31af7Sopenharmony_ciusing tcu::IVec4; 51e5c31af7Sopenharmony_ciusing tcu::Mat3; 52e5c31af7Sopenharmony_ciusing std::string; 53e5c31af7Sopenharmony_ciusing std::vector; 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_cinamespace deqp 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_ci 58e5c31af7Sopenharmony_ciusing namespace gls::TextureTestUtil; 59e5c31af7Sopenharmony_ciusing namespace glu::TextureTestUtil; 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ciusing glu::TextureTestUtil::TEXTURETYPE_2D; 62e5c31af7Sopenharmony_ciusing glu::TextureTestUtil::TEXTURETYPE_CUBE; 63e5c31af7Sopenharmony_ciusing glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY; 64e5c31af7Sopenharmony_ciusing glu::TextureTestUtil::TEXTURETYPE_3D; 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_cinamespace gles3 67e5c31af7Sopenharmony_ci{ 68e5c31af7Sopenharmony_cinamespace Functional 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_cistatic const int WIDTH_2D_ARRAY = 128; 72e5c31af7Sopenharmony_cistatic const int HEIGHT_2D_ARRAY = 128; 73e5c31af7Sopenharmony_cistatic const int LAYERS_2D_ARRAY = 8; 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_cistatic const int WIDTH_3D = 64; 76e5c31af7Sopenharmony_cistatic const int HEIGHT_3D = 64; 77e5c31af7Sopenharmony_cistatic const int DEPTH_3D = 64; 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci// The 2D case draws four images. 80e5c31af7Sopenharmony_cistatic const int MAX_2D_RENDER_WIDTH = 128*2; 81e5c31af7Sopenharmony_cistatic const int MAX_2D_RENDER_HEIGHT = 128*2; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci// The cube map case draws four 3-by-2 image groups. 84e5c31af7Sopenharmony_cistatic const int MAX_CUBE_RENDER_WIDTH = 28*2*3; 85e5c31af7Sopenharmony_cistatic const int MAX_CUBE_RENDER_HEIGHT = 28*2*2; 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_cistatic const int MAX_2D_ARRAY_RENDER_WIDTH = 128*2; 88e5c31af7Sopenharmony_cistatic const int MAX_2D_ARRAY_RENDER_HEIGHT = 128*2; 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_cistatic const int MAX_3D_RENDER_WIDTH = 128*2; 91e5c31af7Sopenharmony_cistatic const int MAX_3D_RENDER_HEIGHT = 128*2; 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_cistatic const int GRID_SIZE_2D = 127; 94e5c31af7Sopenharmony_cistatic const int GRID_SIZE_CUBE = 63; 95e5c31af7Sopenharmony_cistatic const int GRID_SIZE_2D_ARRAY = 127; 96e5c31af7Sopenharmony_cistatic const int GRID_SIZE_3D = 127; 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci// Helpers for making texture coordinates "safe", i.e. move them further from coordinate bounary. 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci// Moves x towards the closest K+targetFraction, where K is an integer. 101e5c31af7Sopenharmony_ci// E.g. moveTowardsFraction(x, 0.5f) moves x away from integer boundaries. 102e5c31af7Sopenharmony_cistatic inline float moveTowardsFraction (float x, float targetFraction) 103e5c31af7Sopenharmony_ci{ 104e5c31af7Sopenharmony_ci const float strictness = 0.5f; 105e5c31af7Sopenharmony_ci DE_ASSERT(0.0f < strictness && strictness <= 1.0f); 106e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(targetFraction, 0.0f, 1.0f)); 107e5c31af7Sopenharmony_ci const float y = x + 0.5f - targetFraction; 108e5c31af7Sopenharmony_ci return deFloatFloor(y) + deFloatFrac(y)*(1.0f-strictness) + strictness*0.5f - 0.5f + targetFraction; 109e5c31af7Sopenharmony_ci} 110e5c31af7Sopenharmony_ci 111e5c31af7Sopenharmony_cistatic inline float safeCoord (float raw, int scale, float fraction) 112e5c31af7Sopenharmony_ci{ 113e5c31af7Sopenharmony_ci const float scaleFloat = (float)scale; 114e5c31af7Sopenharmony_ci return moveTowardsFraction(raw*scaleFloat, fraction) / scaleFloat; 115e5c31af7Sopenharmony_ci} 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_citemplate <int Size> 118e5c31af7Sopenharmony_cistatic inline tcu::Vector<float, Size> safeCoords (const tcu::Vector<float, Size>& raw, const tcu::Vector<int, Size>& scale, const tcu::Vector<float, Size>& fraction) 119e5c31af7Sopenharmony_ci{ 120e5c31af7Sopenharmony_ci tcu::Vector<float, Size> result; 121e5c31af7Sopenharmony_ci for (int i = 0; i < Size; i++) 122e5c31af7Sopenharmony_ci result[i] = safeCoord(raw[i], scale[i], fraction[i]); 123e5c31af7Sopenharmony_ci return result; 124e5c31af7Sopenharmony_ci} 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_cistatic inline Vec2 safe2DTexCoords (const Vec2& raw, const IVec2& textureSize) 127e5c31af7Sopenharmony_ci{ 128e5c31af7Sopenharmony_ci return safeCoords(raw, textureSize, Vec2(0.5f)); 129e5c31af7Sopenharmony_ci} 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_cistatic inline Vec3 safe2DArrayTexCoords (const Vec3& raw, const IVec3& textureSize) 132e5c31af7Sopenharmony_ci{ 133e5c31af7Sopenharmony_ci return safeCoords(raw, textureSize, Vec3(0.5f, 0.5f, 0.0f)); 134e5c31af7Sopenharmony_ci} 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_cistatic inline Vec3 safe3DTexCoords (const Vec3& raw, const IVec3& textureSize) 137e5c31af7Sopenharmony_ci{ 138e5c31af7Sopenharmony_ci return safeCoords(raw, textureSize, Vec3(0.5f)); 139e5c31af7Sopenharmony_ci} 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_cinamespace 142e5c31af7Sopenharmony_ci{ 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_cistruct Rect 145e5c31af7Sopenharmony_ci{ 146e5c31af7Sopenharmony_ci Rect (int x_, int y_, int w_, int h_) : x(x_), y(y_), w(w_), h(h_) {} 147e5c31af7Sopenharmony_ci IVec2 pos (void) const { return IVec2(x, y); } 148e5c31af7Sopenharmony_ci IVec2 size (void) const { return IVec2(w, h); } 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci int x; 151e5c31af7Sopenharmony_ci int y; 152e5c31af7Sopenharmony_ci int w; 153e5c31af7Sopenharmony_ci int h; 154e5c31af7Sopenharmony_ci}; 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_citemplate <TextureType> struct TexTypeTcuClass; 157e5c31af7Sopenharmony_citemplate <> struct TexTypeTcuClass<TEXTURETYPE_2D> { typedef tcu::Texture2D t; }; 158e5c31af7Sopenharmony_citemplate <> struct TexTypeTcuClass<TEXTURETYPE_CUBE> { typedef tcu::TextureCube t; }; 159e5c31af7Sopenharmony_citemplate <> struct TexTypeTcuClass<TEXTURETYPE_2D_ARRAY> { typedef tcu::Texture2DArray t; }; 160e5c31af7Sopenharmony_citemplate <> struct TexTypeTcuClass<TEXTURETYPE_3D> { typedef tcu::Texture3D t; }; 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_citemplate <TextureType> struct TexTypeSizeDims; 163e5c31af7Sopenharmony_citemplate <> struct TexTypeSizeDims<TEXTURETYPE_2D> { enum { V = 2 }; }; 164e5c31af7Sopenharmony_citemplate <> struct TexTypeSizeDims<TEXTURETYPE_CUBE> { enum { V = 2 }; }; 165e5c31af7Sopenharmony_citemplate <> struct TexTypeSizeDims<TEXTURETYPE_2D_ARRAY> { enum { V = 3 }; }; 166e5c31af7Sopenharmony_citemplate <> struct TexTypeSizeDims<TEXTURETYPE_3D> { enum { V = 3 }; }; 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_citemplate <TextureType> struct TexTypeCoordDims; 169e5c31af7Sopenharmony_citemplate <> struct TexTypeCoordDims<TEXTURETYPE_2D> { enum { V = 2 }; }; 170e5c31af7Sopenharmony_citemplate <> struct TexTypeCoordDims<TEXTURETYPE_CUBE> { enum { V = 3 }; }; 171e5c31af7Sopenharmony_citemplate <> struct TexTypeCoordDims<TEXTURETYPE_2D_ARRAY> { enum { V = 3 }; }; 172e5c31af7Sopenharmony_citemplate <> struct TexTypeCoordDims<TEXTURETYPE_3D> { enum { V = 3 }; }; 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_citemplate <TextureType TexType> struct TexTypeSizeIVec { typedef tcu::Vector<int, TexTypeSizeDims<TexType>::V> t; }; 175e5c31af7Sopenharmony_citemplate <TextureType TexType> struct TexTypeCoordVec { typedef tcu::Vector<float, TexTypeCoordDims<TexType>::V> t; }; 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_citemplate <TextureType> struct TexTypeCoordParams; 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_citemplate <> struct 180e5c31af7Sopenharmony_ciTexTypeCoordParams<TEXTURETYPE_2D> 181e5c31af7Sopenharmony_ci{ 182e5c31af7Sopenharmony_ci Vec2 scale; 183e5c31af7Sopenharmony_ci Vec2 bias; 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci TexTypeCoordParams (const Vec2& scale_, const Vec2& bias_) : scale(scale_), bias(bias_) {} 186e5c31af7Sopenharmony_ci}; 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_citemplate <> struct 189e5c31af7Sopenharmony_ciTexTypeCoordParams<TEXTURETYPE_CUBE> 190e5c31af7Sopenharmony_ci{ 191e5c31af7Sopenharmony_ci Vec2 scale; 192e5c31af7Sopenharmony_ci Vec2 bias; 193e5c31af7Sopenharmony_ci tcu::CubeFace face; 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci TexTypeCoordParams (const Vec2& scale_, const Vec2& bias_, tcu::CubeFace face_) : scale(scale_), bias(bias_), face(face_) {} 196e5c31af7Sopenharmony_ci}; 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_citemplate <> struct 199e5c31af7Sopenharmony_ciTexTypeCoordParams<TEXTURETYPE_2D_ARRAY> 200e5c31af7Sopenharmony_ci{ 201e5c31af7Sopenharmony_ci Mat3 transform; 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci TexTypeCoordParams (const Mat3& transform_) : transform(transform_) {} 204e5c31af7Sopenharmony_ci}; 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_citemplate <> struct 207e5c31af7Sopenharmony_ciTexTypeCoordParams<TEXTURETYPE_3D> 208e5c31af7Sopenharmony_ci{ 209e5c31af7Sopenharmony_ci Mat3 transform; 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci TexTypeCoordParams (const Mat3& transform_) : transform(transform_) {} 212e5c31af7Sopenharmony_ci}; 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 215e5c31af7Sopenharmony_ci * \brief Quad grid class containing position and texture coordinate data. 216e5c31af7Sopenharmony_ci * 217e5c31af7Sopenharmony_ci * A quad grid of size S means a grid consisting of S*S quads (S rows and 218e5c31af7Sopenharmony_ci * S columns). The quads are rectangles with main axis aligned sides, and 219e5c31af7Sopenharmony_ci * each consists of two triangles. Note that although there are only 220e5c31af7Sopenharmony_ci * (S+1)*(S+1) distinct vertex positions, there are S*S*4 distinct vertices 221e5c31af7Sopenharmony_ci * because we want texture coordinates to be constant across the vertices 222e5c31af7Sopenharmony_ci * of a quad (to avoid interpolation issues), and thus each quad needs its 223e5c31af7Sopenharmony_ci * own 4 vertices. 224e5c31af7Sopenharmony_ci * 225e5c31af7Sopenharmony_ci * Pointers returned by get*Ptr() are suitable for gl calls such as 226e5c31af7Sopenharmony_ci * glVertexAttribPointer() (for position and tex coord) or glDrawElements() 227e5c31af7Sopenharmony_ci * (for indices). 228e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 229e5c31af7Sopenharmony_citemplate <TextureType TexType> 230e5c31af7Sopenharmony_ciclass PosTexCoordQuadGrid 231e5c31af7Sopenharmony_ci{ 232e5c31af7Sopenharmony_ciprivate: 233e5c31af7Sopenharmony_ci enum { TEX_COORD_DIMS = TexTypeCoordDims <TexType>::V }; 234e5c31af7Sopenharmony_ci typedef typename TexTypeCoordVec<TexType>::t TexCoordVec; 235e5c31af7Sopenharmony_ci typedef typename TexTypeSizeIVec<TexType>::t TexSizeIVec; 236e5c31af7Sopenharmony_ci typedef TexTypeCoordParams<TexType> TexCoordParams; 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_cipublic: 239e5c31af7Sopenharmony_ci PosTexCoordQuadGrid (int gridSize, const IVec2& renderSize, const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords); 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci int getSize (void) const { return m_gridSize; } 242e5c31af7Sopenharmony_ci Vec4 getQuadLDRU (int col, int row) const; //!< Vec4(leftX, downY, rightX, upY) 243e5c31af7Sopenharmony_ci const TexCoordVec& getQuadTexCoord (int col, int row) const; 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ci int getNumIndices (void) const { return m_gridSize*m_gridSize*3*2; } 246e5c31af7Sopenharmony_ci const float* getPositionPtr (void) const { DE_STATIC_ASSERT(sizeof(Vec2) == 2*sizeof(float)); return (float*)&m_positions[0]; } 247e5c31af7Sopenharmony_ci const float* getTexCoordPtr (void) const { DE_STATIC_ASSERT(sizeof(TexCoordVec) == TEX_COORD_DIMS*(int)sizeof(float)); return (float*)&m_texCoords[0]; } 248e5c31af7Sopenharmony_ci const deUint16* getIndexPtr (void) const { return &m_indices[0]; } 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ciprivate: 251e5c31af7Sopenharmony_ci void initializeTexCoords (const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci const int m_gridSize; 254e5c31af7Sopenharmony_ci vector<Vec2> m_positions; 255e5c31af7Sopenharmony_ci vector<TexCoordVec> m_texCoords; 256e5c31af7Sopenharmony_ci vector<deUint16> m_indices; 257e5c31af7Sopenharmony_ci}; 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_citemplate <TextureType TexType> 260e5c31af7Sopenharmony_ciVec4 PosTexCoordQuadGrid<TexType>::getQuadLDRU (int col, int row) const 261e5c31af7Sopenharmony_ci{ 262e5c31af7Sopenharmony_ci int ndx00 = (row*m_gridSize + col) * 4; 263e5c31af7Sopenharmony_ci int ndx11 = ndx00 + 3; 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_ci return Vec4(m_positions[ndx00].x(), 266e5c31af7Sopenharmony_ci m_positions[ndx00].y(), 267e5c31af7Sopenharmony_ci m_positions[ndx11].x(), 268e5c31af7Sopenharmony_ci m_positions[ndx11].y()); 269e5c31af7Sopenharmony_ci} 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_citemplate <TextureType TexType> 272e5c31af7Sopenharmony_ciconst typename TexTypeCoordVec<TexType>::t& PosTexCoordQuadGrid<TexType>::getQuadTexCoord (int col, int row) const 273e5c31af7Sopenharmony_ci{ 274e5c31af7Sopenharmony_ci return m_texCoords[(row*m_gridSize + col) * 4]; 275e5c31af7Sopenharmony_ci} 276e5c31af7Sopenharmony_ci 277e5c31af7Sopenharmony_citemplate <TextureType TexType> 278e5c31af7Sopenharmony_ciPosTexCoordQuadGrid<TexType>::PosTexCoordQuadGrid (int gridSize, const IVec2& renderSize, const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords) 279e5c31af7Sopenharmony_ci : m_gridSize(gridSize) 280e5c31af7Sopenharmony_ci{ 281e5c31af7Sopenharmony_ci DE_ASSERT(m_gridSize > 0 && m_gridSize*m_gridSize <= (int)std::numeric_limits<deUint16>::max() + 1); 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_ci const float gridSizeFloat = (float)m_gridSize; 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ci m_positions.reserve(m_gridSize*m_gridSize*4); 286e5c31af7Sopenharmony_ci m_indices.reserve(m_gridSize*m_gridSize*3*2); 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci for (int y = 0; y < m_gridSize; y++) 289e5c31af7Sopenharmony_ci for (int x = 0; x < m_gridSize; x++) 290e5c31af7Sopenharmony_ci { 291e5c31af7Sopenharmony_ci float fx0 = (float)(x+0) / gridSizeFloat; 292e5c31af7Sopenharmony_ci float fx1 = (float)(x+1) / gridSizeFloat; 293e5c31af7Sopenharmony_ci float fy0 = (float)(y+0) / gridSizeFloat; 294e5c31af7Sopenharmony_ci float fy1 = (float)(y+1) / gridSizeFloat; 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ci Vec2 quadVertices[4] = { Vec2(fx0, fy0), Vec2(fx1, fy0), Vec2(fx0, fy1), Vec2(fx1, fy1) }; 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci int firstNdx = (int)m_positions.size(); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci for (int i = 0; i < DE_LENGTH_OF_ARRAY(quadVertices); i++) 301e5c31af7Sopenharmony_ci m_positions.push_back(safeCoords(quadVertices[i], renderSize, Vec2(0.0f)) * 2.0f - 1.0f); 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci m_indices.push_back(deUint16(firstNdx + 0)); 304e5c31af7Sopenharmony_ci m_indices.push_back(deUint16(firstNdx + 1)); 305e5c31af7Sopenharmony_ci m_indices.push_back(deUint16(firstNdx + 2)); 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ci m_indices.push_back(deUint16(firstNdx + 1)); 308e5c31af7Sopenharmony_ci m_indices.push_back(deUint16(firstNdx + 3)); 309e5c31af7Sopenharmony_ci m_indices.push_back(deUint16(firstNdx + 2)); 310e5c31af7Sopenharmony_ci } 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci m_texCoords.reserve(m_gridSize*m_gridSize*4); 313e5c31af7Sopenharmony_ci initializeTexCoords(textureSize, texCoordParams, useSafeTexCoords); 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci DE_ASSERT((int)m_positions.size() == m_gridSize*m_gridSize*4); 316e5c31af7Sopenharmony_ci DE_ASSERT((int)m_indices.size() == m_gridSize*m_gridSize*3*2); 317e5c31af7Sopenharmony_ci DE_ASSERT((int)m_texCoords.size() == m_gridSize*m_gridSize*4); 318e5c31af7Sopenharmony_ci} 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_citemplate <> 321e5c31af7Sopenharmony_civoid PosTexCoordQuadGrid<TEXTURETYPE_2D>::initializeTexCoords (const IVec2& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords) 322e5c31af7Sopenharmony_ci{ 323e5c31af7Sopenharmony_ci DE_ASSERT(m_texCoords.empty()); 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_ci const float gridSizeFloat = (float)m_gridSize; 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci for (int y = 0; y < m_gridSize; y++) 328e5c31af7Sopenharmony_ci for (int x = 0; x < m_gridSize; x++) 329e5c31af7Sopenharmony_ci { 330e5c31af7Sopenharmony_ci Vec2 rawCoord = Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) * texCoordParams.scale + texCoordParams.bias; 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 333e5c31af7Sopenharmony_ci m_texCoords.push_back(useSafeTexCoords ? safe2DTexCoords(rawCoord, textureSize) : rawCoord); 334e5c31af7Sopenharmony_ci } 335e5c31af7Sopenharmony_ci} 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_citemplate <> 338e5c31af7Sopenharmony_civoid PosTexCoordQuadGrid<TEXTURETYPE_CUBE>::initializeTexCoords (const IVec2& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords) 339e5c31af7Sopenharmony_ci{ 340e5c31af7Sopenharmony_ci DE_ASSERT(m_texCoords.empty()); 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_ci const float gridSizeFloat = (float)m_gridSize; 343e5c31af7Sopenharmony_ci vector<float> texBoundaries; 344e5c31af7Sopenharmony_ci computeQuadTexCoordCube(texBoundaries, texCoordParams.face); 345e5c31af7Sopenharmony_ci const Vec3 coordA = Vec3(texBoundaries[0], texBoundaries[1], texBoundaries[2]); 346e5c31af7Sopenharmony_ci const Vec3 coordB = Vec3(texBoundaries[3], texBoundaries[4], texBoundaries[5]); 347e5c31af7Sopenharmony_ci const Vec3 coordC = Vec3(texBoundaries[6], texBoundaries[7], texBoundaries[8]); 348e5c31af7Sopenharmony_ci const Vec3 coordAB = coordB - coordA; 349e5c31af7Sopenharmony_ci const Vec3 coordAC = coordC - coordA; 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci for (int y = 0; y < m_gridSize; y++) 352e5c31af7Sopenharmony_ci for (int x = 0; x < m_gridSize; x++) 353e5c31af7Sopenharmony_ci { 354e5c31af7Sopenharmony_ci const Vec2 rawFaceCoord = texCoordParams.scale * Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) + texCoordParams.bias; 355e5c31af7Sopenharmony_ci const Vec2 safeFaceCoord = useSafeTexCoords ? safe2DTexCoords(rawFaceCoord, textureSize) : rawFaceCoord; 356e5c31af7Sopenharmony_ci const Vec3 texCoord = coordA + coordAC*safeFaceCoord.x() + coordAB*safeFaceCoord.y(); 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 359e5c31af7Sopenharmony_ci m_texCoords.push_back(texCoord); 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci} 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_citemplate <> 364e5c31af7Sopenharmony_civoid PosTexCoordQuadGrid<TEXTURETYPE_2D_ARRAY>::initializeTexCoords (const IVec3& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords) 365e5c31af7Sopenharmony_ci{ 366e5c31af7Sopenharmony_ci DE_ASSERT(m_texCoords.empty()); 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci const float gridSizeFloat = (float)m_gridSize; 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci for (int y = 0; y < m_gridSize; y++) 371e5c31af7Sopenharmony_ci for (int x = 0; x < m_gridSize; x++) 372e5c31af7Sopenharmony_ci { 373e5c31af7Sopenharmony_ci const Vec3 rawCoord = texCoordParams.transform * Vec3((float)x / gridSizeFloat, (float)y / gridSizeFloat, 1.0f); 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 376e5c31af7Sopenharmony_ci m_texCoords.push_back(useSafeTexCoords ? safe2DArrayTexCoords(rawCoord, textureSize) : rawCoord); 377e5c31af7Sopenharmony_ci } 378e5c31af7Sopenharmony_ci} 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_citemplate <> 381e5c31af7Sopenharmony_civoid PosTexCoordQuadGrid<TEXTURETYPE_3D>::initializeTexCoords (const IVec3& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords) 382e5c31af7Sopenharmony_ci{ 383e5c31af7Sopenharmony_ci DE_ASSERT(m_texCoords.empty()); 384e5c31af7Sopenharmony_ci 385e5c31af7Sopenharmony_ci const float gridSizeFloat = (float)m_gridSize; 386e5c31af7Sopenharmony_ci 387e5c31af7Sopenharmony_ci for (int y = 0; y < m_gridSize; y++) 388e5c31af7Sopenharmony_ci for (int x = 0; x < m_gridSize; x++) 389e5c31af7Sopenharmony_ci { 390e5c31af7Sopenharmony_ci Vec3 rawCoord = texCoordParams.transform * Vec3((float)x / gridSizeFloat, (float)y / gridSizeFloat, 1.0f); 391e5c31af7Sopenharmony_ci 392e5c31af7Sopenharmony_ci for (int i = 0; i < 4; i++) 393e5c31af7Sopenharmony_ci m_texCoords.push_back(useSafeTexCoords ? safe3DTexCoords(rawCoord, textureSize) : rawCoord); 394e5c31af7Sopenharmony_ci } 395e5c31af7Sopenharmony_ci} 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci} // anonymous 398e5c31af7Sopenharmony_ci 399e5c31af7Sopenharmony_cistatic inline bool isLevelNearest (deUint32 filter) 400e5c31af7Sopenharmony_ci{ 401e5c31af7Sopenharmony_ci return filter == GL_NEAREST || filter == GL_NEAREST_MIPMAP_NEAREST || filter == GL_NEAREST_MIPMAP_LINEAR; 402e5c31af7Sopenharmony_ci} 403e5c31af7Sopenharmony_ci 404e5c31af7Sopenharmony_cistatic inline IVec2 getTextureSize (const glu::Texture2D& tex) 405e5c31af7Sopenharmony_ci{ 406e5c31af7Sopenharmony_ci const tcu::Texture2D& ref = tex.getRefTexture(); 407e5c31af7Sopenharmony_ci return IVec2(ref.getWidth(), ref.getHeight()); 408e5c31af7Sopenharmony_ci} 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_cistatic inline IVec2 getTextureSize (const glu::TextureCube& tex) 411e5c31af7Sopenharmony_ci{ 412e5c31af7Sopenharmony_ci const tcu::TextureCube& ref = tex.getRefTexture(); 413e5c31af7Sopenharmony_ci return IVec2(ref.getSize(), ref.getSize()); 414e5c31af7Sopenharmony_ci} 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_cistatic inline IVec3 getTextureSize (const glu::Texture2DArray& tex) 417e5c31af7Sopenharmony_ci{ 418e5c31af7Sopenharmony_ci const tcu::Texture2DArray& ref = tex.getRefTexture(); 419e5c31af7Sopenharmony_ci return IVec3(ref.getWidth(), ref.getHeight(), ref.getNumLayers()); 420e5c31af7Sopenharmony_ci} 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_cistatic inline IVec3 getTextureSize (const glu::Texture3D& tex) 423e5c31af7Sopenharmony_ci{ 424e5c31af7Sopenharmony_ci const tcu::Texture3D& ref = tex.getRefTexture(); 425e5c31af7Sopenharmony_ci return IVec3(ref.getWidth(), ref.getHeight(), ref.getDepth()); 426e5c31af7Sopenharmony_ci} 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_citemplate <TextureType TexType> 429e5c31af7Sopenharmony_cistatic void setPixelColors (const vector<Vec4>& quadColors, const Rect& region, const PosTexCoordQuadGrid<TexType>& grid, tcu::Surface& dst) 430e5c31af7Sopenharmony_ci{ 431e5c31af7Sopenharmony_ci const int gridSize = grid.getSize(); 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci for (int y = 0; y < gridSize; y++) 434e5c31af7Sopenharmony_ci for (int x = 0; x < gridSize; x++) 435e5c31af7Sopenharmony_ci { 436e5c31af7Sopenharmony_ci const Vec4 color = quadColors[y*gridSize + x]; 437e5c31af7Sopenharmony_ci const Vec4 ldru = grid.getQuadLDRU(x, y) * 0.5f + 0.5f; // [-1, 1] -> [0, 1] 438e5c31af7Sopenharmony_ci const int ix0 = deCeilFloatToInt32(ldru.x() * (float)region.w - 0.5f); 439e5c31af7Sopenharmony_ci const int ix1 = deCeilFloatToInt32(ldru.z() * (float)region.w - 0.5f); 440e5c31af7Sopenharmony_ci const int iy0 = deCeilFloatToInt32(ldru.y() * (float)region.h - 0.5f); 441e5c31af7Sopenharmony_ci const int iy1 = deCeilFloatToInt32(ldru.w() * (float)region.h - 0.5f); 442e5c31af7Sopenharmony_ci 443e5c31af7Sopenharmony_ci for (int iy = iy0; iy < iy1; iy++) 444e5c31af7Sopenharmony_ci for (int ix = ix0; ix < ix1; ix++) 445e5c31af7Sopenharmony_ci { 446e5c31af7Sopenharmony_ci DE_ASSERT(deInBounds32(ix + region.x, 0, dst.getWidth())); 447e5c31af7Sopenharmony_ci DE_ASSERT(deInBounds32(iy + region.y, 0, dst.getHeight())); 448e5c31af7Sopenharmony_ci 449e5c31af7Sopenharmony_ci dst.setPixel(ix + region.x, iy + region.y, tcu::RGBA(color)); 450e5c31af7Sopenharmony_ci } 451e5c31af7Sopenharmony_ci } 452e5c31af7Sopenharmony_ci} 453e5c31af7Sopenharmony_ci 454e5c31af7Sopenharmony_cistatic inline Vec4 sample (const tcu::Texture2D& tex, const Vec2& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), lod); } 455e5c31af7Sopenharmony_cistatic inline Vec4 sample (const tcu::TextureCube& tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); } 456e5c31af7Sopenharmony_cistatic inline Vec4 sample (const tcu::Texture2DArray& tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); } 457e5c31af7Sopenharmony_cistatic inline Vec4 sample (const tcu::Texture3D& tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); } 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_citemplate <TextureType TexType> 460e5c31af7Sopenharmony_civoid computeReference (const typename TexTypeTcuClass<TexType>::t& texture, float lod, const tcu::Sampler& sampler, const PosTexCoordQuadGrid<TexType>& grid, tcu::Surface& dst, const Rect& dstRegion) 461e5c31af7Sopenharmony_ci{ 462e5c31af7Sopenharmony_ci const int gridSize = grid.getSize(); 463e5c31af7Sopenharmony_ci vector<Vec4> quadColors (gridSize*gridSize); 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ci for (int y = 0; y < gridSize; y++) 466e5c31af7Sopenharmony_ci for (int x = 0; x < gridSize; x++) 467e5c31af7Sopenharmony_ci { 468e5c31af7Sopenharmony_ci const int ndx = y*gridSize + x; 469e5c31af7Sopenharmony_ci const typename TexTypeCoordVec<TexType>::t& coord = grid.getQuadTexCoord(x, y); 470e5c31af7Sopenharmony_ci 471e5c31af7Sopenharmony_ci quadColors[ndx] = sample(texture, coord, lod, sampler); 472e5c31af7Sopenharmony_ci } 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci setPixelColors(quadColors, dstRegion, grid, dst); 475e5c31af7Sopenharmony_ci} 476e5c31af7Sopenharmony_ci 477e5c31af7Sopenharmony_cistatic bool compareImages (const glu::RenderContext& renderCtx, tcu::TestLog& log, const tcu::Surface& ref, const tcu::Surface& res) 478e5c31af7Sopenharmony_ci{ 479e5c31af7Sopenharmony_ci DE_ASSERT(renderCtx.getRenderTarget().getNumSamples() == 0); 480e5c31af7Sopenharmony_ci 481e5c31af7Sopenharmony_ci const tcu::RGBA threshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(15,15,15,15); 482e5c31af7Sopenharmony_ci return tcu::pixelThresholdCompare(log, "Result", "Image compare result", ref, res, threshold, tcu::COMPARE_LOG_RESULT); 483e5c31af7Sopenharmony_ci} 484e5c31af7Sopenharmony_ci 485e5c31af7Sopenharmony_ciclass Vertex2DTextureCase : public TestCase 486e5c31af7Sopenharmony_ci{ 487e5c31af7Sopenharmony_cipublic: 488e5c31af7Sopenharmony_ci Vertex2DTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT); 489e5c31af7Sopenharmony_ci ~Vertex2DTextureCase (void); 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci void init (void); 492e5c31af7Sopenharmony_ci void deinit (void); 493e5c31af7Sopenharmony_ci IterateResult iterate (void); 494e5c31af7Sopenharmony_ci 495e5c31af7Sopenharmony_ciprivate: 496e5c31af7Sopenharmony_ci typedef PosTexCoordQuadGrid<TEXTURETYPE_2D> Grid; 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_ci Vertex2DTextureCase (const Vertex2DTextureCase& other); 499e5c31af7Sopenharmony_ci Vertex2DTextureCase& operator= (const Vertex2DTextureCase& other); 500e5c31af7Sopenharmony_ci 501e5c31af7Sopenharmony_ci float calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const; 502e5c31af7Sopenharmony_ci void setupShaderInputs (int textureNdx, float lod, const Grid& grid) const; 503e5c31af7Sopenharmony_ci void renderCell (int textureNdx, float lod, const Grid& grid) const; 504e5c31af7Sopenharmony_ci void computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const; 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci const deUint32 m_minFilter; 507e5c31af7Sopenharmony_ci const deUint32 m_magFilter; 508e5c31af7Sopenharmony_ci const deUint32 m_wrapS; 509e5c31af7Sopenharmony_ci const deUint32 m_wrapT; 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci const glu::ShaderProgram* m_program; 512e5c31af7Sopenharmony_ci glu::Texture2D* m_textures[2]; // 2 textures, a gradient texture and a grid texture. 513e5c31af7Sopenharmony_ci}; 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ciVertex2DTextureCase::Vertex2DTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT) 516e5c31af7Sopenharmony_ci : TestCase (testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc) 517e5c31af7Sopenharmony_ci , m_minFilter (minFilter) 518e5c31af7Sopenharmony_ci , m_magFilter (magFilter) 519e5c31af7Sopenharmony_ci , m_wrapS (wrapS) 520e5c31af7Sopenharmony_ci , m_wrapT (wrapT) 521e5c31af7Sopenharmony_ci , m_program (DE_NULL) 522e5c31af7Sopenharmony_ci{ 523e5c31af7Sopenharmony_ci m_textures[0] = DE_NULL; 524e5c31af7Sopenharmony_ci m_textures[1] = DE_NULL; 525e5c31af7Sopenharmony_ci} 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_ciVertex2DTextureCase::~Vertex2DTextureCase(void) 528e5c31af7Sopenharmony_ci{ 529e5c31af7Sopenharmony_ci Vertex2DTextureCase::deinit(); 530e5c31af7Sopenharmony_ci} 531e5c31af7Sopenharmony_ci 532e5c31af7Sopenharmony_civoid Vertex2DTextureCase::init (void) 533e5c31af7Sopenharmony_ci{ 534e5c31af7Sopenharmony_ci const char* const vertexShader = 535e5c31af7Sopenharmony_ci "#version 300 es\n" 536e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 537e5c31af7Sopenharmony_ci "in highp vec2 a_texCoord;\n" 538e5c31af7Sopenharmony_ci "uniform highp sampler2D u_texture;\n" 539e5c31af7Sopenharmony_ci "uniform highp float u_lod;\n" 540e5c31af7Sopenharmony_ci "out mediump vec4 v_color;\n" 541e5c31af7Sopenharmony_ci "\n" 542e5c31af7Sopenharmony_ci "void main()\n" 543e5c31af7Sopenharmony_ci "{\n" 544e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 545e5c31af7Sopenharmony_ci " v_color = textureLod(u_texture, a_texCoord, u_lod);\n" 546e5c31af7Sopenharmony_ci "}\n"; 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci const char* const fragmentShader = 549e5c31af7Sopenharmony_ci "#version 300 es\n" 550e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" 551e5c31af7Sopenharmony_ci "in mediump vec4 v_color;\n" 552e5c31af7Sopenharmony_ci "\n" 553e5c31af7Sopenharmony_ci "void main()\n" 554e5c31af7Sopenharmony_ci "{\n" 555e5c31af7Sopenharmony_ci " dEQP_FragColor = v_color;\n" 556e5c31af7Sopenharmony_ci "}\n"; 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci if (m_context.getRenderTarget().getNumSamples() != 0) 559e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("MSAA config not supported by this test"); 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ci DE_ASSERT(!m_program); 562e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader)); 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ci if(!m_program->isOk()) 565e5c31af7Sopenharmony_ci { 566e5c31af7Sopenharmony_ci m_testCtx.getLog() << *m_program; 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_ci GLint maxVertexTextures; 569e5c31af7Sopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures); 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci if (maxVertexTextures < 1) 572e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__); 573e5c31af7Sopenharmony_ci else 574e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile shader"); 575e5c31af7Sopenharmony_ci } 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ci // Make the textures. 578e5c31af7Sopenharmony_ci try 579e5c31af7Sopenharmony_ci { 580e5c31af7Sopenharmony_ci // Compute suitable power-of-two sizes (for mipmaps). 581e5c31af7Sopenharmony_ci const int texWidth = 1 << deLog2Ceil32(MAX_2D_RENDER_WIDTH / 2); 582e5c31af7Sopenharmony_ci const int texHeight = 1 << deLog2Ceil32(MAX_2D_RENDER_HEIGHT / 2); 583e5c31af7Sopenharmony_ci 584e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 585e5c31af7Sopenharmony_ci { 586e5c31af7Sopenharmony_ci DE_ASSERT(!m_textures[i]); 587e5c31af7Sopenharmony_ci m_textures[i] = new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight); 588e5c31af7Sopenharmony_ci } 589e5c31af7Sopenharmony_ci 590e5c31af7Sopenharmony_ci const bool mipmaps = (deIsPowerOfTwo32(texWidth) && deIsPowerOfTwo32(texHeight)); 591e5c31af7Sopenharmony_ci const int numLevels = mipmaps ? deLog2Floor32(de::max(texWidth, texHeight))+1 : 1; 592e5c31af7Sopenharmony_ci const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat()); 593e5c31af7Sopenharmony_ci const Vec4 cBias = fmtInfo.valueMin; 594e5c31af7Sopenharmony_ci const Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin; 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci // Fill first with gradient texture. 597e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 598e5c31af7Sopenharmony_ci { 599e5c31af7Sopenharmony_ci const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias; 600e5c31af7Sopenharmony_ci const Vec4 gMax = Vec4( 1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias; 601e5c31af7Sopenharmony_ci 602e5c31af7Sopenharmony_ci m_textures[0]->getRefTexture().allocLevel(levelNdx); 603e5c31af7Sopenharmony_ci tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax); 604e5c31af7Sopenharmony_ci } 605e5c31af7Sopenharmony_ci 606e5c31af7Sopenharmony_ci // Fill second with grid texture. 607e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 608e5c31af7Sopenharmony_ci { 609e5c31af7Sopenharmony_ci const deUint32 step = 0x00ffffff / numLevels; 610e5c31af7Sopenharmony_ci const deUint32 rgb = step*levelNdx; 611e5c31af7Sopenharmony_ci const deUint32 colorA = 0xff000000 | rgb; 612e5c31af7Sopenharmony_ci const deUint32 colorB = 0xff000000 | ~rgb; 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_ci m_textures[1]->getRefTexture().allocLevel(levelNdx); 615e5c31af7Sopenharmony_ci tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias); 616e5c31af7Sopenharmony_ci } 617e5c31af7Sopenharmony_ci 618e5c31af7Sopenharmony_ci // Upload. 619e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 620e5c31af7Sopenharmony_ci m_textures[i]->upload(); 621e5c31af7Sopenharmony_ci } 622e5c31af7Sopenharmony_ci catch (const std::exception&) 623e5c31af7Sopenharmony_ci { 624e5c31af7Sopenharmony_ci // Clean up to save memory. 625e5c31af7Sopenharmony_ci Vertex2DTextureCase::deinit(); 626e5c31af7Sopenharmony_ci throw; 627e5c31af7Sopenharmony_ci } 628e5c31af7Sopenharmony_ci} 629e5c31af7Sopenharmony_ci 630e5c31af7Sopenharmony_civoid Vertex2DTextureCase::deinit (void) 631e5c31af7Sopenharmony_ci{ 632e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 633e5c31af7Sopenharmony_ci { 634e5c31af7Sopenharmony_ci delete m_textures[i]; 635e5c31af7Sopenharmony_ci m_textures[i] = DE_NULL; 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci delete m_program; 639e5c31af7Sopenharmony_ci m_program = DE_NULL; 640e5c31af7Sopenharmony_ci} 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_cifloat Vertex2DTextureCase::calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const 643e5c31af7Sopenharmony_ci{ 644e5c31af7Sopenharmony_ci const tcu::Texture2D& refTexture = m_textures[textureNdx]->getRefTexture(); 645e5c31af7Sopenharmony_ci const Vec2 srcSize = Vec2((float)refTexture.getWidth(), (float)refTexture.getHeight()); 646e5c31af7Sopenharmony_ci const Vec2 sizeRatio = texScale*srcSize / dstSize; 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci // \note In this particular case dv/dx and du/dy are zero, simplifying the expression. 649e5c31af7Sopenharmony_ci return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y())); 650e5c31af7Sopenharmony_ci} 651e5c31af7Sopenharmony_ci 652e5c31af7Sopenharmony_ciVertex2DTextureCase::IterateResult Vertex2DTextureCase::iterate (void) 653e5c31af7Sopenharmony_ci{ 654e5c31af7Sopenharmony_ci const int viewportWidth = deMin32(m_context.getRenderTarget().getWidth(), MAX_2D_RENDER_WIDTH); 655e5c31af7Sopenharmony_ci const int viewportHeight = deMin32(m_context.getRenderTarget().getHeight(), MAX_2D_RENDER_HEIGHT); 656e5c31af7Sopenharmony_ci 657e5c31af7Sopenharmony_ci const int viewportXOffsetMax = m_context.getRenderTarget().getWidth() - viewportWidth; 658e5c31af7Sopenharmony_ci const int viewportYOffsetMax = m_context.getRenderTarget().getHeight() - viewportHeight; 659e5c31af7Sopenharmony_ci 660e5c31af7Sopenharmony_ci de::Random rnd (deStringHash(getName())); 661e5c31af7Sopenharmony_ci 662e5c31af7Sopenharmony_ci const int viewportXOffset = rnd.getInt(0, viewportXOffsetMax); 663e5c31af7Sopenharmony_ci const int viewportYOffset = rnd.getInt(0, viewportYOffsetMax); 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci glUseProgram(m_program->getProgram()); 666e5c31af7Sopenharmony_ci 667e5c31af7Sopenharmony_ci // Divide viewport into 4 cells. 668e5c31af7Sopenharmony_ci const int leftWidth = viewportWidth / 2; 669e5c31af7Sopenharmony_ci const int rightWidth = viewportWidth - leftWidth; 670e5c31af7Sopenharmony_ci const int bottomHeight = viewportHeight / 2; 671e5c31af7Sopenharmony_ci const int topHeight = viewportHeight - bottomHeight; 672e5c31af7Sopenharmony_ci 673e5c31af7Sopenharmony_ci // Clear. 674e5c31af7Sopenharmony_ci glClearColor(0.125f, 0.25f, 0.5f, 1.0f); 675e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT); 676e5c31af7Sopenharmony_ci 677e5c31af7Sopenharmony_ci // Texture scaling and offsetting vectors. 678e5c31af7Sopenharmony_ci const Vec2 texMinScale (+1.8f, +1.8f); 679e5c31af7Sopenharmony_ci const Vec2 texMinOffset (-0.3f, -0.2f); 680e5c31af7Sopenharmony_ci const Vec2 texMagScale (+0.3f, +0.3f); 681e5c31af7Sopenharmony_ci const Vec2 texMagOffset (+0.9f, +0.8f); 682e5c31af7Sopenharmony_ci 683e5c31af7Sopenharmony_ci // Surface for the reference image. 684e5c31af7Sopenharmony_ci tcu::Surface refImage(viewportWidth, viewportHeight); 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci { 687e5c31af7Sopenharmony_ci const struct Render 688e5c31af7Sopenharmony_ci { 689e5c31af7Sopenharmony_ci const Rect region; 690e5c31af7Sopenharmony_ci int textureNdx; 691e5c31af7Sopenharmony_ci const Vec2 texCoordScale; 692e5c31af7Sopenharmony_ci const Vec2 texCoordOffset; 693e5c31af7Sopenharmony_ci Render (const Rect& r, int tN, const Vec2& tS, const Vec2& tO) : region(r), textureNdx(tN), texCoordScale(tS), texCoordOffset(tO) {} 694e5c31af7Sopenharmony_ci } renders[] = 695e5c31af7Sopenharmony_ci { 696e5c31af7Sopenharmony_ci Render(Rect(0, 0, leftWidth, bottomHeight), 0, texMinScale, texMinOffset), 697e5c31af7Sopenharmony_ci Render(Rect(leftWidth, 0, rightWidth, bottomHeight), 0, texMagScale, texMagOffset), 698e5c31af7Sopenharmony_ci Render(Rect(0, bottomHeight, leftWidth, topHeight), 1, texMinScale, texMinOffset), 699e5c31af7Sopenharmony_ci Render(Rect(leftWidth, bottomHeight, rightWidth, topHeight), 1, texMagScale, texMagOffset) 700e5c31af7Sopenharmony_ci }; 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++) 703e5c31af7Sopenharmony_ci { 704e5c31af7Sopenharmony_ci const Render& rend = renders[renderNdx]; 705e5c31af7Sopenharmony_ci const float lod = calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx); 706e5c31af7Sopenharmony_ci const bool useSafeTexCoords = isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter); 707e5c31af7Sopenharmony_ci const Grid grid (GRID_SIZE_2D, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]), 708e5c31af7Sopenharmony_ci TexTypeCoordParams<TEXTURETYPE_2D>(rend.texCoordScale, rend.texCoordOffset), useSafeTexCoords); 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h); 711e5c31af7Sopenharmony_ci renderCell (rend.textureNdx, lod, grid); 712e5c31af7Sopenharmony_ci computeReferenceCell (rend.textureNdx, lod, grid, refImage, rend.region); 713e5c31af7Sopenharmony_ci } 714e5c31af7Sopenharmony_ci } 715e5c31af7Sopenharmony_ci 716e5c31af7Sopenharmony_ci // Read back rendered results. 717e5c31af7Sopenharmony_ci tcu::Surface resImage(viewportWidth, viewportHeight); 718e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess()); 719e5c31af7Sopenharmony_ci 720e5c31af7Sopenharmony_ci glUseProgram(0); 721e5c31af7Sopenharmony_ci 722e5c31af7Sopenharmony_ci // Compare and log. 723e5c31af7Sopenharmony_ci { 724e5c31af7Sopenharmony_ci const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage); 725e5c31af7Sopenharmony_ci 726e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 727e5c31af7Sopenharmony_ci isOk ? "Pass" : "Image comparison failed"); 728e5c31af7Sopenharmony_ci } 729e5c31af7Sopenharmony_ci 730e5c31af7Sopenharmony_ci return STOP; 731e5c31af7Sopenharmony_ci} 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_civoid Vertex2DTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const 734e5c31af7Sopenharmony_ci{ 735e5c31af7Sopenharmony_ci const deUint32 programID = m_program->getProgram(); 736e5c31af7Sopenharmony_ci 737e5c31af7Sopenharmony_ci // SETUP ATTRIBUTES. 738e5c31af7Sopenharmony_ci 739e5c31af7Sopenharmony_ci { 740e5c31af7Sopenharmony_ci const int positionLoc = glGetAttribLocation(programID, "a_position"); 741e5c31af7Sopenharmony_ci if (positionLoc != -1) 742e5c31af7Sopenharmony_ci { 743e5c31af7Sopenharmony_ci glEnableVertexAttribArray(positionLoc); 744e5c31af7Sopenharmony_ci glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr()); 745e5c31af7Sopenharmony_ci } 746e5c31af7Sopenharmony_ci } 747e5c31af7Sopenharmony_ci 748e5c31af7Sopenharmony_ci { 749e5c31af7Sopenharmony_ci const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord"); 750e5c31af7Sopenharmony_ci if (texCoordLoc != -1) 751e5c31af7Sopenharmony_ci { 752e5c31af7Sopenharmony_ci glEnableVertexAttribArray(texCoordLoc); 753e5c31af7Sopenharmony_ci glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr()); 754e5c31af7Sopenharmony_ci } 755e5c31af7Sopenharmony_ci } 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_ci // SETUP UNIFORMS. 758e5c31af7Sopenharmony_ci 759e5c31af7Sopenharmony_ci { 760e5c31af7Sopenharmony_ci const int lodLoc = glGetUniformLocation(programID, "u_lod"); 761e5c31af7Sopenharmony_ci if (lodLoc != -1) 762e5c31af7Sopenharmony_ci glUniform1f(lodLoc, lod); 763e5c31af7Sopenharmony_ci } 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_ci glActiveTexture(GL_TEXTURE0); 766e5c31af7Sopenharmony_ci glBindTexture(GL_TEXTURE_2D, m_textures[textureNdx]->getGLTexture()); 767e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS); 768e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT); 769e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter); 770e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter); 771e5c31af7Sopenharmony_ci 772e5c31af7Sopenharmony_ci { 773e5c31af7Sopenharmony_ci const int texLoc = glGetUniformLocation(programID, "u_texture"); 774e5c31af7Sopenharmony_ci if (texLoc != -1) 775e5c31af7Sopenharmony_ci glUniform1i(texLoc, 0); 776e5c31af7Sopenharmony_ci } 777e5c31af7Sopenharmony_ci} 778e5c31af7Sopenharmony_ci 779e5c31af7Sopenharmony_ci// Renders one sub-image with given parameters. 780e5c31af7Sopenharmony_civoid Vertex2DTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const 781e5c31af7Sopenharmony_ci{ 782e5c31af7Sopenharmony_ci setupShaderInputs(textureNdx, lod, grid); 783e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr()); 784e5c31af7Sopenharmony_ci} 785e5c31af7Sopenharmony_ci 786e5c31af7Sopenharmony_civoid Vertex2DTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const 787e5c31af7Sopenharmony_ci{ 788e5c31af7Sopenharmony_ci computeReference(m_textures[textureNdx]->getRefTexture(), lod, glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter), grid, dst, dstRegion); 789e5c31af7Sopenharmony_ci} 790e5c31af7Sopenharmony_ci 791e5c31af7Sopenharmony_ciclass VertexCubeTextureCase : public TestCase 792e5c31af7Sopenharmony_ci{ 793e5c31af7Sopenharmony_cipublic: 794e5c31af7Sopenharmony_ci VertexCubeTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT); 795e5c31af7Sopenharmony_ci ~VertexCubeTextureCase (void); 796e5c31af7Sopenharmony_ci 797e5c31af7Sopenharmony_ci void init (void); 798e5c31af7Sopenharmony_ci void deinit (void); 799e5c31af7Sopenharmony_ci IterateResult iterate (void); 800e5c31af7Sopenharmony_ci 801e5c31af7Sopenharmony_ciprivate: 802e5c31af7Sopenharmony_ci typedef PosTexCoordQuadGrid<TEXTURETYPE_CUBE> Grid; 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci VertexCubeTextureCase (const VertexCubeTextureCase& other); 805e5c31af7Sopenharmony_ci VertexCubeTextureCase& operator= (const VertexCubeTextureCase& other); 806e5c31af7Sopenharmony_ci 807e5c31af7Sopenharmony_ci float calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const; 808e5c31af7Sopenharmony_ci void setupShaderInputs (int textureNdx, float lod, const Grid& grid) const; 809e5c31af7Sopenharmony_ci void renderCell (int textureNdx, float lod, const Grid& grid) const; 810e5c31af7Sopenharmony_ci void computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const; 811e5c31af7Sopenharmony_ci 812e5c31af7Sopenharmony_ci const deUint32 m_minFilter; 813e5c31af7Sopenharmony_ci const deUint32 m_magFilter; 814e5c31af7Sopenharmony_ci const deUint32 m_wrapS; 815e5c31af7Sopenharmony_ci const deUint32 m_wrapT; 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci const glu::ShaderProgram* m_program; 818e5c31af7Sopenharmony_ci glu::TextureCube* m_textures[2]; // 2 textures, a gradient texture and a grid texture. 819e5c31af7Sopenharmony_ci}; 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ciVertexCubeTextureCase::VertexCubeTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT) 822e5c31af7Sopenharmony_ci : TestCase (testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc) 823e5c31af7Sopenharmony_ci , m_minFilter (minFilter) 824e5c31af7Sopenharmony_ci , m_magFilter (magFilter) 825e5c31af7Sopenharmony_ci , m_wrapS (wrapS) 826e5c31af7Sopenharmony_ci , m_wrapT (wrapT) 827e5c31af7Sopenharmony_ci , m_program (DE_NULL) 828e5c31af7Sopenharmony_ci{ 829e5c31af7Sopenharmony_ci m_textures[0] = DE_NULL; 830e5c31af7Sopenharmony_ci m_textures[1] = DE_NULL; 831e5c31af7Sopenharmony_ci} 832e5c31af7Sopenharmony_ci 833e5c31af7Sopenharmony_ciVertexCubeTextureCase::~VertexCubeTextureCase(void) 834e5c31af7Sopenharmony_ci{ 835e5c31af7Sopenharmony_ci VertexCubeTextureCase::deinit(); 836e5c31af7Sopenharmony_ci} 837e5c31af7Sopenharmony_ci 838e5c31af7Sopenharmony_civoid VertexCubeTextureCase::init (void) 839e5c31af7Sopenharmony_ci{ 840e5c31af7Sopenharmony_ci const char* const vertexShader = 841e5c31af7Sopenharmony_ci "#version 300 es\n" 842e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 843e5c31af7Sopenharmony_ci "in highp vec3 a_texCoord;\n" 844e5c31af7Sopenharmony_ci "uniform highp samplerCube u_texture;\n" 845e5c31af7Sopenharmony_ci "uniform highp float u_lod;\n" 846e5c31af7Sopenharmony_ci "out mediump vec4 v_color;\n" 847e5c31af7Sopenharmony_ci "\n" 848e5c31af7Sopenharmony_ci "void main()\n" 849e5c31af7Sopenharmony_ci "{\n" 850e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 851e5c31af7Sopenharmony_ci " v_color = textureLod(u_texture, a_texCoord, u_lod);\n" 852e5c31af7Sopenharmony_ci "}\n"; 853e5c31af7Sopenharmony_ci 854e5c31af7Sopenharmony_ci const char* const fragmentShader = 855e5c31af7Sopenharmony_ci "#version 300 es\n" 856e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" 857e5c31af7Sopenharmony_ci "in mediump vec4 v_color;\n" 858e5c31af7Sopenharmony_ci "\n" 859e5c31af7Sopenharmony_ci "void main()\n" 860e5c31af7Sopenharmony_ci "{\n" 861e5c31af7Sopenharmony_ci " dEQP_FragColor = v_color;\n" 862e5c31af7Sopenharmony_ci "}\n"; 863e5c31af7Sopenharmony_ci 864e5c31af7Sopenharmony_ci if (m_context.getRenderTarget().getNumSamples() != 0) 865e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("MSAA config not supported by this test"); 866e5c31af7Sopenharmony_ci 867e5c31af7Sopenharmony_ci DE_ASSERT(!m_program); 868e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader)); 869e5c31af7Sopenharmony_ci 870e5c31af7Sopenharmony_ci if(!m_program->isOk()) 871e5c31af7Sopenharmony_ci { 872e5c31af7Sopenharmony_ci m_testCtx.getLog() << *m_program; 873e5c31af7Sopenharmony_ci 874e5c31af7Sopenharmony_ci GLint maxVertexTextures; 875e5c31af7Sopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures); 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci if (maxVertexTextures < 1) 878e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__); 879e5c31af7Sopenharmony_ci else 880e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile shader"); 881e5c31af7Sopenharmony_ci } 882e5c31af7Sopenharmony_ci 883e5c31af7Sopenharmony_ci // Make the textures. 884e5c31af7Sopenharmony_ci try 885e5c31af7Sopenharmony_ci { 886e5c31af7Sopenharmony_ci // Compute suitable power-of-two sizes (for mipmaps). 887e5c31af7Sopenharmony_ci const int texWidth = 1 << deLog2Ceil32(MAX_CUBE_RENDER_WIDTH / 3 / 2); 888e5c31af7Sopenharmony_ci const int texHeight = 1 << deLog2Ceil32(MAX_CUBE_RENDER_HEIGHT / 2 / 2); 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_ci DE_ASSERT(texWidth == texHeight); 891e5c31af7Sopenharmony_ci DE_UNREF(texHeight); 892e5c31af7Sopenharmony_ci 893e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 894e5c31af7Sopenharmony_ci { 895e5c31af7Sopenharmony_ci DE_ASSERT(!m_textures[i]); 896e5c31af7Sopenharmony_ci m_textures[i] = new glu::TextureCube(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth); 897e5c31af7Sopenharmony_ci } 898e5c31af7Sopenharmony_ci 899e5c31af7Sopenharmony_ci const bool mipmaps = deIsPowerOfTwo32(texWidth) != DE_FALSE; 900e5c31af7Sopenharmony_ci const int numLevels = mipmaps ? deLog2Floor32(texWidth)+1 : 1; 901e5c31af7Sopenharmony_ci const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat()); 902e5c31af7Sopenharmony_ci const Vec4 cBias = fmtInfo.valueMin; 903e5c31af7Sopenharmony_ci const Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin; 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ci // Fill first with gradient texture. 906e5c31af7Sopenharmony_ci static const Vec4 gradients[tcu::CUBEFACE_LAST][2] = 907e5c31af7Sopenharmony_ci { 908e5c31af7Sopenharmony_ci { Vec4(-1.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x 909e5c31af7Sopenharmony_ci { Vec4( 0.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x 910e5c31af7Sopenharmony_ci { Vec4(-1.0f, 0.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y 911e5c31af7Sopenharmony_ci { Vec4(-1.0f, -1.0f, 0.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y 912e5c31af7Sopenharmony_ci { Vec4(-1.0f, -1.0f, -1.0f, 0.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z 913e5c31af7Sopenharmony_ci { Vec4( 0.0f, 0.0f, 0.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) } // positive z 914e5c31af7Sopenharmony_ci }; 915e5c31af7Sopenharmony_ci for (int face = 0; face < tcu::CUBEFACE_LAST; face++) 916e5c31af7Sopenharmony_ci { 917e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 918e5c31af7Sopenharmony_ci { 919e5c31af7Sopenharmony_ci m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx); 920e5c31af7Sopenharmony_ci tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias); 921e5c31af7Sopenharmony_ci } 922e5c31af7Sopenharmony_ci } 923e5c31af7Sopenharmony_ci 924e5c31af7Sopenharmony_ci // Fill second with grid texture. 925e5c31af7Sopenharmony_ci for (int face = 0; face < tcu::CUBEFACE_LAST; face++) 926e5c31af7Sopenharmony_ci { 927e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 928e5c31af7Sopenharmony_ci { 929e5c31af7Sopenharmony_ci const deUint32 step = 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST); 930e5c31af7Sopenharmony_ci const deUint32 rgb = step*levelNdx*face; 931e5c31af7Sopenharmony_ci const deUint32 colorA = 0xff000000 | rgb; 932e5c31af7Sopenharmony_ci const deUint32 colorB = 0xff000000 | ~rgb; 933e5c31af7Sopenharmony_ci 934e5c31af7Sopenharmony_ci m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx); 935e5c31af7Sopenharmony_ci tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias); 936e5c31af7Sopenharmony_ci } 937e5c31af7Sopenharmony_ci } 938e5c31af7Sopenharmony_ci 939e5c31af7Sopenharmony_ci // Upload. 940e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 941e5c31af7Sopenharmony_ci m_textures[i]->upload(); 942e5c31af7Sopenharmony_ci } 943e5c31af7Sopenharmony_ci catch (const std::exception&) 944e5c31af7Sopenharmony_ci { 945e5c31af7Sopenharmony_ci // Clean up to save memory. 946e5c31af7Sopenharmony_ci VertexCubeTextureCase::deinit(); 947e5c31af7Sopenharmony_ci throw; 948e5c31af7Sopenharmony_ci } 949e5c31af7Sopenharmony_ci} 950e5c31af7Sopenharmony_ci 951e5c31af7Sopenharmony_civoid VertexCubeTextureCase::deinit (void) 952e5c31af7Sopenharmony_ci{ 953e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 954e5c31af7Sopenharmony_ci { 955e5c31af7Sopenharmony_ci delete m_textures[i]; 956e5c31af7Sopenharmony_ci m_textures[i] = DE_NULL; 957e5c31af7Sopenharmony_ci } 958e5c31af7Sopenharmony_ci 959e5c31af7Sopenharmony_ci delete m_program; 960e5c31af7Sopenharmony_ci m_program = DE_NULL; 961e5c31af7Sopenharmony_ci} 962e5c31af7Sopenharmony_ci 963e5c31af7Sopenharmony_cifloat VertexCubeTextureCase::calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const 964e5c31af7Sopenharmony_ci{ 965e5c31af7Sopenharmony_ci const tcu::TextureCube& refTexture = m_textures[textureNdx]->getRefTexture(); 966e5c31af7Sopenharmony_ci const Vec2 srcSize = Vec2((float)refTexture.getSize(), (float)refTexture.getSize()); 967e5c31af7Sopenharmony_ci const Vec2 sizeRatio = texScale*srcSize / dstSize; 968e5c31af7Sopenharmony_ci 969e5c31af7Sopenharmony_ci // \note In this particular case, dv/dx and du/dy are zero, simplifying the expression. 970e5c31af7Sopenharmony_ci return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y())); 971e5c31af7Sopenharmony_ci} 972e5c31af7Sopenharmony_ci 973e5c31af7Sopenharmony_ciVertexCubeTextureCase::IterateResult VertexCubeTextureCase::iterate (void) 974e5c31af7Sopenharmony_ci{ 975e5c31af7Sopenharmony_ci const int viewportWidth = deMin32(m_context.getRenderTarget().getWidth(), MAX_CUBE_RENDER_WIDTH); 976e5c31af7Sopenharmony_ci const int viewportHeight = deMin32(m_context.getRenderTarget().getHeight(), MAX_CUBE_RENDER_HEIGHT); 977e5c31af7Sopenharmony_ci 978e5c31af7Sopenharmony_ci const int viewportXOffsetMax = m_context.getRenderTarget().getWidth() - viewportWidth; 979e5c31af7Sopenharmony_ci const int viewportYOffsetMax = m_context.getRenderTarget().getHeight() - viewportHeight; 980e5c31af7Sopenharmony_ci 981e5c31af7Sopenharmony_ci de::Random rnd (deStringHash(getName())); 982e5c31af7Sopenharmony_ci 983e5c31af7Sopenharmony_ci const int viewportXOffset = rnd.getInt(0, viewportXOffsetMax); 984e5c31af7Sopenharmony_ci const int viewportYOffset = rnd.getInt(0, viewportYOffsetMax); 985e5c31af7Sopenharmony_ci 986e5c31af7Sopenharmony_ci glUseProgram(m_program->getProgram()); 987e5c31af7Sopenharmony_ci 988e5c31af7Sopenharmony_ci // Divide viewport into 4 areas. 989e5c31af7Sopenharmony_ci const int leftWidth = viewportWidth / 2; 990e5c31af7Sopenharmony_ci const int rightWidth = viewportWidth - leftWidth; 991e5c31af7Sopenharmony_ci const int bottomHeight = viewportHeight / 2; 992e5c31af7Sopenharmony_ci const int topHeight = viewportHeight - bottomHeight; 993e5c31af7Sopenharmony_ci 994e5c31af7Sopenharmony_ci // Clear. 995e5c31af7Sopenharmony_ci glClearColor(0.125f, 0.25f, 0.5f, 1.0f); 996e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT); 997e5c31af7Sopenharmony_ci 998e5c31af7Sopenharmony_ci // Texture scaling and offsetting vectors. 999e5c31af7Sopenharmony_ci const Vec2 texMinScale (1.0f, 1.0f); 1000e5c31af7Sopenharmony_ci const Vec2 texMinOffset (0.0f, 0.0f); 1001e5c31af7Sopenharmony_ci const Vec2 texMagScale (0.3f, 0.3f); 1002e5c31af7Sopenharmony_ci const Vec2 texMagOffset (0.5f, 0.3f); 1003e5c31af7Sopenharmony_ci 1004e5c31af7Sopenharmony_ci // Surface for the reference image. 1005e5c31af7Sopenharmony_ci tcu::Surface refImage(viewportWidth, viewportHeight); 1006e5c31af7Sopenharmony_ci 1007e5c31af7Sopenharmony_ci // Each of the four areas is divided into 6 cells. 1008e5c31af7Sopenharmony_ci const int defCellWidth = viewportWidth / 2 / 3; 1009e5c31af7Sopenharmony_ci const int defCellHeight = viewportHeight / 2 / 2; 1010e5c31af7Sopenharmony_ci 1011e5c31af7Sopenharmony_ci for (int i = 0; i < tcu::CUBEFACE_LAST; i++) 1012e5c31af7Sopenharmony_ci { 1013e5c31af7Sopenharmony_ci const int cellOffsetX = defCellWidth * (i % 3); 1014e5c31af7Sopenharmony_ci const int cellOffsetY = defCellHeight * (i / 3); 1015e5c31af7Sopenharmony_ci const bool isRightmostCell = i == 2 || i == 5; 1016e5c31af7Sopenharmony_ci const bool isTopCell = i >= 3; 1017e5c31af7Sopenharmony_ci const int leftCellWidth = isRightmostCell ? leftWidth - cellOffsetX : defCellWidth; 1018e5c31af7Sopenharmony_ci const int rightCellWidth = isRightmostCell ? rightWidth - cellOffsetX : defCellWidth; 1019e5c31af7Sopenharmony_ci const int bottomCellHeight = isTopCell ? bottomHeight - cellOffsetY : defCellHeight; 1020e5c31af7Sopenharmony_ci const int topCellHeight = isTopCell ? topHeight - cellOffsetY : defCellHeight; 1021e5c31af7Sopenharmony_ci 1022e5c31af7Sopenharmony_ci const struct Render 1023e5c31af7Sopenharmony_ci { 1024e5c31af7Sopenharmony_ci const Rect region; 1025e5c31af7Sopenharmony_ci int textureNdx; 1026e5c31af7Sopenharmony_ci const Vec2 texCoordScale; 1027e5c31af7Sopenharmony_ci const Vec2 texCoordOffset; 1028e5c31af7Sopenharmony_ci Render (const Rect& r, int tN, const Vec2& tS, const Vec2& tO) : region(r), textureNdx(tN), texCoordScale(tS), texCoordOffset(tO) {} 1029e5c31af7Sopenharmony_ci } renders[] = 1030e5c31af7Sopenharmony_ci { 1031e5c31af7Sopenharmony_ci Render(Rect(cellOffsetX + 0, cellOffsetY + 0, leftCellWidth, bottomCellHeight), 0, texMinScale, texMinOffset), 1032e5c31af7Sopenharmony_ci Render(Rect(cellOffsetX + leftWidth, cellOffsetY + 0, rightCellWidth, bottomCellHeight), 0, texMagScale, texMagOffset), 1033e5c31af7Sopenharmony_ci Render(Rect(cellOffsetX + 0, cellOffsetY + bottomHeight, leftCellWidth, topCellHeight), 1, texMinScale, texMinOffset), 1034e5c31af7Sopenharmony_ci Render(Rect(cellOffsetX + leftWidth, cellOffsetY + bottomHeight, rightCellWidth, topCellHeight), 1, texMagScale, texMagOffset) 1035e5c31af7Sopenharmony_ci }; 1036e5c31af7Sopenharmony_ci 1037e5c31af7Sopenharmony_ci for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++) 1038e5c31af7Sopenharmony_ci { 1039e5c31af7Sopenharmony_ci const Render& rend = renders[renderNdx]; 1040e5c31af7Sopenharmony_ci const float lod = calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx); 1041e5c31af7Sopenharmony_ci const bool useSafeTexCoords = isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter); 1042e5c31af7Sopenharmony_ci const Grid grid (GRID_SIZE_CUBE, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]), 1043e5c31af7Sopenharmony_ci TexTypeCoordParams<TEXTURETYPE_CUBE>(rend.texCoordScale, rend.texCoordOffset, (tcu::CubeFace)i), useSafeTexCoords); 1044e5c31af7Sopenharmony_ci 1045e5c31af7Sopenharmony_ci glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h); 1046e5c31af7Sopenharmony_ci renderCell (rend.textureNdx, lod, grid); 1047e5c31af7Sopenharmony_ci computeReferenceCell (rend.textureNdx, lod, grid, refImage, rend.region); 1048e5c31af7Sopenharmony_ci } 1049e5c31af7Sopenharmony_ci } 1050e5c31af7Sopenharmony_ci 1051e5c31af7Sopenharmony_ci // Read back rendered results. 1052e5c31af7Sopenharmony_ci tcu::Surface resImage(viewportWidth, viewportHeight); 1053e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess()); 1054e5c31af7Sopenharmony_ci 1055e5c31af7Sopenharmony_ci glUseProgram(0); 1056e5c31af7Sopenharmony_ci 1057e5c31af7Sopenharmony_ci // Compare and log. 1058e5c31af7Sopenharmony_ci { 1059e5c31af7Sopenharmony_ci const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage); 1060e5c31af7Sopenharmony_ci 1061e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 1062e5c31af7Sopenharmony_ci isOk ? "Pass" : "Image comparison failed"); 1063e5c31af7Sopenharmony_ci } 1064e5c31af7Sopenharmony_ci 1065e5c31af7Sopenharmony_ci return STOP; 1066e5c31af7Sopenharmony_ci} 1067e5c31af7Sopenharmony_ci 1068e5c31af7Sopenharmony_civoid VertexCubeTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const 1069e5c31af7Sopenharmony_ci{ 1070e5c31af7Sopenharmony_ci const deUint32 programID = m_program->getProgram(); 1071e5c31af7Sopenharmony_ci 1072e5c31af7Sopenharmony_ci // SETUP ATTRIBUTES. 1073e5c31af7Sopenharmony_ci 1074e5c31af7Sopenharmony_ci { 1075e5c31af7Sopenharmony_ci const int positionLoc = glGetAttribLocation(programID, "a_position"); 1076e5c31af7Sopenharmony_ci if (positionLoc != -1) 1077e5c31af7Sopenharmony_ci { 1078e5c31af7Sopenharmony_ci glEnableVertexAttribArray(positionLoc); 1079e5c31af7Sopenharmony_ci glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr()); 1080e5c31af7Sopenharmony_ci } 1081e5c31af7Sopenharmony_ci } 1082e5c31af7Sopenharmony_ci 1083e5c31af7Sopenharmony_ci { 1084e5c31af7Sopenharmony_ci const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord"); 1085e5c31af7Sopenharmony_ci if (texCoordLoc != -1) 1086e5c31af7Sopenharmony_ci { 1087e5c31af7Sopenharmony_ci glEnableVertexAttribArray(texCoordLoc); 1088e5c31af7Sopenharmony_ci glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr()); 1089e5c31af7Sopenharmony_ci } 1090e5c31af7Sopenharmony_ci } 1091e5c31af7Sopenharmony_ci 1092e5c31af7Sopenharmony_ci // SETUP UNIFORMS. 1093e5c31af7Sopenharmony_ci 1094e5c31af7Sopenharmony_ci { 1095e5c31af7Sopenharmony_ci const int lodLoc = glGetUniformLocation(programID, "u_lod"); 1096e5c31af7Sopenharmony_ci if (lodLoc != -1) 1097e5c31af7Sopenharmony_ci glUniform1f(lodLoc, lod); 1098e5c31af7Sopenharmony_ci } 1099e5c31af7Sopenharmony_ci 1100e5c31af7Sopenharmony_ci glActiveTexture(GL_TEXTURE0); 1101e5c31af7Sopenharmony_ci glBindTexture(GL_TEXTURE_CUBE_MAP, m_textures[textureNdx]->getGLTexture()); 1102e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, m_wrapS); 1103e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, m_wrapT); 1104e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, m_minFilter); 1105e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, m_magFilter); 1106e5c31af7Sopenharmony_ci 1107e5c31af7Sopenharmony_ci { 1108e5c31af7Sopenharmony_ci const int texLoc = glGetUniformLocation(programID, "u_texture"); 1109e5c31af7Sopenharmony_ci if (texLoc != -1) 1110e5c31af7Sopenharmony_ci glUniform1i(texLoc, 0); 1111e5c31af7Sopenharmony_ci } 1112e5c31af7Sopenharmony_ci} 1113e5c31af7Sopenharmony_ci 1114e5c31af7Sopenharmony_ci// Renders one cube face with given parameters. 1115e5c31af7Sopenharmony_civoid VertexCubeTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const 1116e5c31af7Sopenharmony_ci{ 1117e5c31af7Sopenharmony_ci setupShaderInputs(textureNdx, lod, grid); 1118e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr()); 1119e5c31af7Sopenharmony_ci} 1120e5c31af7Sopenharmony_ci 1121e5c31af7Sopenharmony_ci// Computes reference for one cube face with given parameters. 1122e5c31af7Sopenharmony_civoid VertexCubeTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const 1123e5c31af7Sopenharmony_ci{ 1124e5c31af7Sopenharmony_ci tcu::Sampler sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter); 1125e5c31af7Sopenharmony_ci sampler.seamlessCubeMap = true; 1126e5c31af7Sopenharmony_ci computeReference(m_textures[textureNdx]->getRefTexture(), lod, sampler, grid, dst, dstRegion); 1127e5c31af7Sopenharmony_ci} 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ciclass Vertex2DArrayTextureCase : public TestCase 1130e5c31af7Sopenharmony_ci{ 1131e5c31af7Sopenharmony_cipublic: 1132e5c31af7Sopenharmony_ci Vertex2DArrayTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT); 1133e5c31af7Sopenharmony_ci ~Vertex2DArrayTextureCase (void); 1134e5c31af7Sopenharmony_ci 1135e5c31af7Sopenharmony_ci void init (void); 1136e5c31af7Sopenharmony_ci void deinit (void); 1137e5c31af7Sopenharmony_ci IterateResult iterate (void); 1138e5c31af7Sopenharmony_ci 1139e5c31af7Sopenharmony_ciprivate: 1140e5c31af7Sopenharmony_ci typedef PosTexCoordQuadGrid<TEXTURETYPE_2D_ARRAY> Grid; 1141e5c31af7Sopenharmony_ci 1142e5c31af7Sopenharmony_ci Vertex2DArrayTextureCase (const Vertex2DArrayTextureCase& other); 1143e5c31af7Sopenharmony_ci Vertex2DArrayTextureCase& operator= (const Vertex2DArrayTextureCase& other); 1144e5c31af7Sopenharmony_ci 1145e5c31af7Sopenharmony_ci float calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const; 1146e5c31af7Sopenharmony_ci void setupShaderInputs (int textureNdx, float lod, const Grid& grid) const; 1147e5c31af7Sopenharmony_ci void renderCell (int textureNdx, float lod, const Grid& grid) const; 1148e5c31af7Sopenharmony_ci void computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const; 1149e5c31af7Sopenharmony_ci 1150e5c31af7Sopenharmony_ci const deUint32 m_minFilter; 1151e5c31af7Sopenharmony_ci const deUint32 m_magFilter; 1152e5c31af7Sopenharmony_ci const deUint32 m_wrapS; 1153e5c31af7Sopenharmony_ci const deUint32 m_wrapT; 1154e5c31af7Sopenharmony_ci 1155e5c31af7Sopenharmony_ci const glu::ShaderProgram* m_program; 1156e5c31af7Sopenharmony_ci glu::Texture2DArray* m_textures[2]; // 2 textures, a gradient texture and a grid texture. 1157e5c31af7Sopenharmony_ci}; 1158e5c31af7Sopenharmony_ci 1159e5c31af7Sopenharmony_ciVertex2DArrayTextureCase::Vertex2DArrayTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT) 1160e5c31af7Sopenharmony_ci : TestCase (testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc) 1161e5c31af7Sopenharmony_ci , m_minFilter (minFilter) 1162e5c31af7Sopenharmony_ci , m_magFilter (magFilter) 1163e5c31af7Sopenharmony_ci , m_wrapS (wrapS) 1164e5c31af7Sopenharmony_ci , m_wrapT (wrapT) 1165e5c31af7Sopenharmony_ci , m_program (DE_NULL) 1166e5c31af7Sopenharmony_ci{ 1167e5c31af7Sopenharmony_ci m_textures[0] = DE_NULL; 1168e5c31af7Sopenharmony_ci m_textures[1] = DE_NULL; 1169e5c31af7Sopenharmony_ci} 1170e5c31af7Sopenharmony_ci 1171e5c31af7Sopenharmony_ciVertex2DArrayTextureCase::~Vertex2DArrayTextureCase(void) 1172e5c31af7Sopenharmony_ci{ 1173e5c31af7Sopenharmony_ci Vertex2DArrayTextureCase::deinit(); 1174e5c31af7Sopenharmony_ci} 1175e5c31af7Sopenharmony_ci 1176e5c31af7Sopenharmony_civoid Vertex2DArrayTextureCase::init (void) 1177e5c31af7Sopenharmony_ci{ 1178e5c31af7Sopenharmony_ci const char* const vertexShaderSource = 1179e5c31af7Sopenharmony_ci "#version 300 es\n" 1180e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 1181e5c31af7Sopenharmony_ci "in highp vec3 a_texCoord;\n" 1182e5c31af7Sopenharmony_ci "uniform highp sampler2DArray u_texture;\n" 1183e5c31af7Sopenharmony_ci "uniform highp float u_lod;\n" 1184e5c31af7Sopenharmony_ci "out mediump vec4 v_color;\n" 1185e5c31af7Sopenharmony_ci "\n" 1186e5c31af7Sopenharmony_ci "void main()\n" 1187e5c31af7Sopenharmony_ci "{\n" 1188e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 1189e5c31af7Sopenharmony_ci " v_color = textureLod(u_texture, a_texCoord, u_lod);\n" 1190e5c31af7Sopenharmony_ci "}\n"; 1191e5c31af7Sopenharmony_ci 1192e5c31af7Sopenharmony_ci const char* const fragmentShaderSource = 1193e5c31af7Sopenharmony_ci "#version 300 es\n" 1194e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" 1195e5c31af7Sopenharmony_ci "in mediump vec4 v_color;\n" 1196e5c31af7Sopenharmony_ci "\n" 1197e5c31af7Sopenharmony_ci "void main()\n" 1198e5c31af7Sopenharmony_ci "{\n" 1199e5c31af7Sopenharmony_ci " dEQP_FragColor = v_color;\n" 1200e5c31af7Sopenharmony_ci "}\n"; 1201e5c31af7Sopenharmony_ci 1202e5c31af7Sopenharmony_ci if (m_context.getRenderTarget().getNumSamples() != 0) 1203e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("MSAA config not supported by this test"); 1204e5c31af7Sopenharmony_ci 1205e5c31af7Sopenharmony_ci // Create shader. 1206e5c31af7Sopenharmony_ci 1207e5c31af7Sopenharmony_ci DE_ASSERT(!m_program); 1208e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource)); 1209e5c31af7Sopenharmony_ci 1210e5c31af7Sopenharmony_ci if(!m_program->isOk()) 1211e5c31af7Sopenharmony_ci { 1212e5c31af7Sopenharmony_ci m_testCtx.getLog() << *m_program; 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci GLint maxVertexTextures; 1215e5c31af7Sopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures); 1216e5c31af7Sopenharmony_ci 1217e5c31af7Sopenharmony_ci if (maxVertexTextures < 1) 1218e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__); 1219e5c31af7Sopenharmony_ci else 1220e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile shader"); 1221e5c31af7Sopenharmony_ci } 1222e5c31af7Sopenharmony_ci 1223e5c31af7Sopenharmony_ci // Make the textures. 1224e5c31af7Sopenharmony_ci 1225e5c31af7Sopenharmony_ci try 1226e5c31af7Sopenharmony_ci { 1227e5c31af7Sopenharmony_ci const int texWidth = WIDTH_2D_ARRAY; 1228e5c31af7Sopenharmony_ci const int texHeight = HEIGHT_2D_ARRAY; 1229e5c31af7Sopenharmony_ci const int texLayers = LAYERS_2D_ARRAY; 1230e5c31af7Sopenharmony_ci 1231e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 1232e5c31af7Sopenharmony_ci { 1233e5c31af7Sopenharmony_ci DE_ASSERT(!m_textures[i]); 1234e5c31af7Sopenharmony_ci m_textures[i] = new glu::Texture2DArray(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight, texLayers); 1235e5c31af7Sopenharmony_ci } 1236e5c31af7Sopenharmony_ci 1237e5c31af7Sopenharmony_ci const int numLevels = deLog2Floor32(de::max(texWidth, texHeight)) + 1; 1238e5c31af7Sopenharmony_ci const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat()); 1239e5c31af7Sopenharmony_ci const Vec4 cBias = fmtInfo.valueMin; 1240e5c31af7Sopenharmony_ci const Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin; 1241e5c31af7Sopenharmony_ci 1242e5c31af7Sopenharmony_ci // Fill first with gradient texture. 1243e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 1244e5c31af7Sopenharmony_ci { 1245e5c31af7Sopenharmony_ci const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias; 1246e5c31af7Sopenharmony_ci const Vec4 gMax = Vec4( 1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias; 1247e5c31af7Sopenharmony_ci 1248e5c31af7Sopenharmony_ci m_textures[0]->getRefTexture().allocLevel(levelNdx); 1249e5c31af7Sopenharmony_ci tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax); 1250e5c31af7Sopenharmony_ci } 1251e5c31af7Sopenharmony_ci 1252e5c31af7Sopenharmony_ci // Fill second with grid texture. 1253e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 1254e5c31af7Sopenharmony_ci { 1255e5c31af7Sopenharmony_ci const deUint32 step = 0x00ffffff / numLevels; 1256e5c31af7Sopenharmony_ci const deUint32 rgb = step*levelNdx; 1257e5c31af7Sopenharmony_ci const deUint32 colorA = 0xff000000 | rgb; 1258e5c31af7Sopenharmony_ci const deUint32 colorB = 0xff000000 | ~rgb; 1259e5c31af7Sopenharmony_ci 1260e5c31af7Sopenharmony_ci m_textures[1]->getRefTexture().allocLevel(levelNdx); 1261e5c31af7Sopenharmony_ci tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias); 1262e5c31af7Sopenharmony_ci } 1263e5c31af7Sopenharmony_ci 1264e5c31af7Sopenharmony_ci // Upload. 1265e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 1266e5c31af7Sopenharmony_ci m_textures[i]->upload(); 1267e5c31af7Sopenharmony_ci } 1268e5c31af7Sopenharmony_ci catch (const std::exception&) 1269e5c31af7Sopenharmony_ci { 1270e5c31af7Sopenharmony_ci // Clean up to save memory. 1271e5c31af7Sopenharmony_ci Vertex2DArrayTextureCase::deinit(); 1272e5c31af7Sopenharmony_ci throw; 1273e5c31af7Sopenharmony_ci } 1274e5c31af7Sopenharmony_ci} 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_civoid Vertex2DArrayTextureCase::deinit (void) 1277e5c31af7Sopenharmony_ci{ 1278e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 1279e5c31af7Sopenharmony_ci { 1280e5c31af7Sopenharmony_ci delete m_textures[i]; 1281e5c31af7Sopenharmony_ci m_textures[i] = DE_NULL; 1282e5c31af7Sopenharmony_ci } 1283e5c31af7Sopenharmony_ci 1284e5c31af7Sopenharmony_ci delete m_program; 1285e5c31af7Sopenharmony_ci m_program = DE_NULL; 1286e5c31af7Sopenharmony_ci} 1287e5c31af7Sopenharmony_ci 1288e5c31af7Sopenharmony_cifloat Vertex2DArrayTextureCase::calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const 1289e5c31af7Sopenharmony_ci{ 1290e5c31af7Sopenharmony_ci const tcu::Texture2DArray& refTexture = m_textures[textureNdx]->getRefTexture(); 1291e5c31af7Sopenharmony_ci const int texWidth = refTexture.getWidth(); 1292e5c31af7Sopenharmony_ci const int texHeight = refTexture.getHeight(); 1293e5c31af7Sopenharmony_ci 1294e5c31af7Sopenharmony_ci // Calculate transformed coordinates of three screen corners. 1295e5c31af7Sopenharmony_ci const Vec2 trans00 = (transf * Vec3(0.0f, 0.0f, 1.0f)).xy(); 1296e5c31af7Sopenharmony_ci const Vec2 trans01 = (transf * Vec3(0.0f, 1.0f, 1.0f)).xy(); 1297e5c31af7Sopenharmony_ci const Vec2 trans10 = (transf * Vec3(1.0f, 0.0f, 1.0f)).xy(); 1298e5c31af7Sopenharmony_ci 1299e5c31af7Sopenharmony_ci // Derivates. 1300e5c31af7Sopenharmony_ci const float dudx = (trans10.x() - trans00.x()) * (float)texWidth / dstSize.x(); 1301e5c31af7Sopenharmony_ci const float dudy = (trans01.x() - trans00.x()) * (float)texWidth / dstSize.y(); 1302e5c31af7Sopenharmony_ci const float dvdx = (trans10.y() - trans00.y()) * (float)texHeight / dstSize.x(); 1303e5c31af7Sopenharmony_ci const float dvdy = (trans01.y() - trans00.y()) * (float)texHeight / dstSize.y(); 1304e5c31af7Sopenharmony_ci 1305e5c31af7Sopenharmony_ci return deFloatLog2(deFloatSqrt(de::max(dudx*dudx + dvdx*dvdx, dudy*dudy + dvdy*dvdy))); 1306e5c31af7Sopenharmony_ci} 1307e5c31af7Sopenharmony_ci 1308e5c31af7Sopenharmony_ciVertex2DArrayTextureCase::IterateResult Vertex2DArrayTextureCase::iterate (void) 1309e5c31af7Sopenharmony_ci{ 1310e5c31af7Sopenharmony_ci const int viewportWidth = deMin32(m_context.getRenderTarget().getWidth(), MAX_2D_ARRAY_RENDER_WIDTH); 1311e5c31af7Sopenharmony_ci const int viewportHeight = deMin32(m_context.getRenderTarget().getHeight(), MAX_2D_ARRAY_RENDER_HEIGHT); 1312e5c31af7Sopenharmony_ci 1313e5c31af7Sopenharmony_ci const int viewportXOffsetMax = m_context.getRenderTarget().getWidth() - viewportWidth; 1314e5c31af7Sopenharmony_ci const int viewportYOffsetMax = m_context.getRenderTarget().getHeight() - viewportHeight; 1315e5c31af7Sopenharmony_ci 1316e5c31af7Sopenharmony_ci de::Random rnd (deStringHash(getName())); 1317e5c31af7Sopenharmony_ci 1318e5c31af7Sopenharmony_ci const int viewportXOffset = rnd.getInt(0, viewportXOffsetMax); 1319e5c31af7Sopenharmony_ci const int viewportYOffset = rnd.getInt(0, viewportYOffsetMax); 1320e5c31af7Sopenharmony_ci 1321e5c31af7Sopenharmony_ci glUseProgram(m_program->getProgram()); 1322e5c31af7Sopenharmony_ci 1323e5c31af7Sopenharmony_ci // Divide viewport into 4 cells. 1324e5c31af7Sopenharmony_ci const int leftWidth = viewportWidth / 2; 1325e5c31af7Sopenharmony_ci const int rightWidth = viewportWidth - leftWidth; 1326e5c31af7Sopenharmony_ci const int bottomHeight = viewportHeight / 2; 1327e5c31af7Sopenharmony_ci const int topHeight = viewportHeight - bottomHeight; 1328e5c31af7Sopenharmony_ci 1329e5c31af7Sopenharmony_ci // Clear. 1330e5c31af7Sopenharmony_ci glClearColor(0.125f, 0.25f, 0.5f, 1.0f); 1331e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT); 1332e5c31af7Sopenharmony_ci 1333e5c31af7Sopenharmony_ci // Shear by layer count to get all layers visible. 1334e5c31af7Sopenharmony_ci static const float layerShearTransfData[] = 1335e5c31af7Sopenharmony_ci { 1336e5c31af7Sopenharmony_ci 1.0f, 0.0f, 0.0f, 1337e5c31af7Sopenharmony_ci 0.0f, 1.0f, 0.0f, 1338e5c31af7Sopenharmony_ci (float)LAYERS_2D_ARRAY, 0.0f, 0.0f 1339e5c31af7Sopenharmony_ci }; 1340e5c31af7Sopenharmony_ci 1341e5c31af7Sopenharmony_ci // Minification and magnification transformations. 1342e5c31af7Sopenharmony_ci static const float texMinTransfData[] = 1343e5c31af7Sopenharmony_ci { 1344e5c31af7Sopenharmony_ci 2.1f, 0.0f, -0.3f, 1345e5c31af7Sopenharmony_ci 0.0f, 2.1f, -0.3f, 1346e5c31af7Sopenharmony_ci 0.0f, 0.0f, 1.0f 1347e5c31af7Sopenharmony_ci }; 1348e5c31af7Sopenharmony_ci static const float texMagTransfData[] = 1349e5c31af7Sopenharmony_ci { 1350e5c31af7Sopenharmony_ci 0.4f, 0.0f, 0.8f, 1351e5c31af7Sopenharmony_ci 0.0f, 0.4f, 0.8f, 1352e5c31af7Sopenharmony_ci 0.0f, 0.0f, 1.0f 1353e5c31af7Sopenharmony_ci }; 1354e5c31af7Sopenharmony_ci 1355e5c31af7Sopenharmony_ci // Transformation matrices for minification and magnification. 1356e5c31af7Sopenharmony_ci const Mat3 texMinTransf = Mat3(layerShearTransfData) * Mat3(texMinTransfData); 1357e5c31af7Sopenharmony_ci const Mat3 texMagTransf = Mat3(layerShearTransfData) * Mat3(texMagTransfData); 1358e5c31af7Sopenharmony_ci 1359e5c31af7Sopenharmony_ci // Surface for the reference image. 1360e5c31af7Sopenharmony_ci tcu::Surface refImage(viewportWidth, viewportHeight); 1361e5c31af7Sopenharmony_ci 1362e5c31af7Sopenharmony_ci { 1363e5c31af7Sopenharmony_ci const struct Render 1364e5c31af7Sopenharmony_ci { 1365e5c31af7Sopenharmony_ci const Rect region; 1366e5c31af7Sopenharmony_ci int textureNdx; 1367e5c31af7Sopenharmony_ci const Mat3 texTransform; 1368e5c31af7Sopenharmony_ci Render (const Rect& r, int tN, const Mat3& tT) : region(r), textureNdx(tN), texTransform(tT) {} 1369e5c31af7Sopenharmony_ci } renders[] = 1370e5c31af7Sopenharmony_ci { 1371e5c31af7Sopenharmony_ci Render(Rect(0, 0, leftWidth, bottomHeight), 0, texMinTransf), 1372e5c31af7Sopenharmony_ci Render(Rect(leftWidth, 0, rightWidth, bottomHeight), 0, texMagTransf), 1373e5c31af7Sopenharmony_ci Render(Rect(0, bottomHeight, leftWidth, topHeight), 1, texMinTransf), 1374e5c31af7Sopenharmony_ci Render(Rect(leftWidth, bottomHeight, rightWidth, topHeight), 1, texMagTransf) 1375e5c31af7Sopenharmony_ci }; 1376e5c31af7Sopenharmony_ci 1377e5c31af7Sopenharmony_ci for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++) 1378e5c31af7Sopenharmony_ci { 1379e5c31af7Sopenharmony_ci const Render& rend = renders[renderNdx]; 1380e5c31af7Sopenharmony_ci const float lod = calculateLod(rend.texTransform, rend.region.size().asFloat(), rend.textureNdx); 1381e5c31af7Sopenharmony_ci const bool useSafeTexCoords = isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter); 1382e5c31af7Sopenharmony_ci const Grid grid (GRID_SIZE_2D_ARRAY, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]), 1383e5c31af7Sopenharmony_ci TexTypeCoordParams<TEXTURETYPE_2D_ARRAY>(rend.texTransform), useSafeTexCoords); 1384e5c31af7Sopenharmony_ci 1385e5c31af7Sopenharmony_ci glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h); 1386e5c31af7Sopenharmony_ci renderCell (rend.textureNdx, lod, grid); 1387e5c31af7Sopenharmony_ci computeReferenceCell (rend.textureNdx, lod, grid, refImage, rend.region); 1388e5c31af7Sopenharmony_ci } 1389e5c31af7Sopenharmony_ci } 1390e5c31af7Sopenharmony_ci 1391e5c31af7Sopenharmony_ci // Read back rendered results. 1392e5c31af7Sopenharmony_ci tcu::Surface resImage(viewportWidth, viewportHeight); 1393e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess()); 1394e5c31af7Sopenharmony_ci 1395e5c31af7Sopenharmony_ci glUseProgram(0); 1396e5c31af7Sopenharmony_ci 1397e5c31af7Sopenharmony_ci // Compare and log. 1398e5c31af7Sopenharmony_ci { 1399e5c31af7Sopenharmony_ci const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage); 1400e5c31af7Sopenharmony_ci 1401e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 1402e5c31af7Sopenharmony_ci isOk ? "Pass" : "Image comparison failed"); 1403e5c31af7Sopenharmony_ci } 1404e5c31af7Sopenharmony_ci 1405e5c31af7Sopenharmony_ci return STOP; 1406e5c31af7Sopenharmony_ci} 1407e5c31af7Sopenharmony_ci 1408e5c31af7Sopenharmony_civoid Vertex2DArrayTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const 1409e5c31af7Sopenharmony_ci{ 1410e5c31af7Sopenharmony_ci const deUint32 programID = m_program->getProgram(); 1411e5c31af7Sopenharmony_ci 1412e5c31af7Sopenharmony_ci // SETUP ATTRIBUTES. 1413e5c31af7Sopenharmony_ci 1414e5c31af7Sopenharmony_ci { 1415e5c31af7Sopenharmony_ci const int positionLoc = glGetAttribLocation(programID, "a_position"); 1416e5c31af7Sopenharmony_ci if (positionLoc != -1) 1417e5c31af7Sopenharmony_ci { 1418e5c31af7Sopenharmony_ci glEnableVertexAttribArray(positionLoc); 1419e5c31af7Sopenharmony_ci glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr()); 1420e5c31af7Sopenharmony_ci } 1421e5c31af7Sopenharmony_ci } 1422e5c31af7Sopenharmony_ci 1423e5c31af7Sopenharmony_ci { 1424e5c31af7Sopenharmony_ci const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord"); 1425e5c31af7Sopenharmony_ci if (texCoordLoc != -1) 1426e5c31af7Sopenharmony_ci { 1427e5c31af7Sopenharmony_ci glEnableVertexAttribArray(texCoordLoc); 1428e5c31af7Sopenharmony_ci glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr()); 1429e5c31af7Sopenharmony_ci } 1430e5c31af7Sopenharmony_ci } 1431e5c31af7Sopenharmony_ci 1432e5c31af7Sopenharmony_ci // SETUP UNIFORMS. 1433e5c31af7Sopenharmony_ci 1434e5c31af7Sopenharmony_ci { 1435e5c31af7Sopenharmony_ci const int lodLoc = glGetUniformLocation(programID, "u_lod"); 1436e5c31af7Sopenharmony_ci if (lodLoc != -1) 1437e5c31af7Sopenharmony_ci glUniform1f(lodLoc, lod); 1438e5c31af7Sopenharmony_ci } 1439e5c31af7Sopenharmony_ci 1440e5c31af7Sopenharmony_ci glActiveTexture(GL_TEXTURE0); 1441e5c31af7Sopenharmony_ci glBindTexture(GL_TEXTURE_2D_ARRAY, m_textures[textureNdx]->getGLTexture()); 1442e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, m_wrapS); 1443e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, m_wrapT); 1444e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, m_minFilter); 1445e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, m_magFilter); 1446e5c31af7Sopenharmony_ci 1447e5c31af7Sopenharmony_ci { 1448e5c31af7Sopenharmony_ci const int texLoc = glGetUniformLocation(programID, "u_texture"); 1449e5c31af7Sopenharmony_ci if (texLoc != -1) 1450e5c31af7Sopenharmony_ci glUniform1i(texLoc, 0); 1451e5c31af7Sopenharmony_ci } 1452e5c31af7Sopenharmony_ci} 1453e5c31af7Sopenharmony_ci 1454e5c31af7Sopenharmony_ci// Renders one sub-image with given parameters. 1455e5c31af7Sopenharmony_civoid Vertex2DArrayTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const 1456e5c31af7Sopenharmony_ci{ 1457e5c31af7Sopenharmony_ci setupShaderInputs(textureNdx, lod, grid); 1458e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr()); 1459e5c31af7Sopenharmony_ci} 1460e5c31af7Sopenharmony_ci 1461e5c31af7Sopenharmony_ci// Computes reference for one sub-image with given parameters. 1462e5c31af7Sopenharmony_civoid Vertex2DArrayTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const 1463e5c31af7Sopenharmony_ci{ 1464e5c31af7Sopenharmony_ci computeReference(m_textures[textureNdx]->getRefTexture(), lod, glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter), grid, dst, dstRegion); 1465e5c31af7Sopenharmony_ci} 1466e5c31af7Sopenharmony_ci 1467e5c31af7Sopenharmony_ciclass Vertex3DTextureCase : public TestCase 1468e5c31af7Sopenharmony_ci{ 1469e5c31af7Sopenharmony_cipublic: 1470e5c31af7Sopenharmony_ci Vertex3DTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR); 1471e5c31af7Sopenharmony_ci ~Vertex3DTextureCase (void); 1472e5c31af7Sopenharmony_ci 1473e5c31af7Sopenharmony_ci void init (void); 1474e5c31af7Sopenharmony_ci void deinit (void); 1475e5c31af7Sopenharmony_ci IterateResult iterate (void); 1476e5c31af7Sopenharmony_ci 1477e5c31af7Sopenharmony_ciprivate: 1478e5c31af7Sopenharmony_ci typedef PosTexCoordQuadGrid<TEXTURETYPE_3D> Grid; 1479e5c31af7Sopenharmony_ci 1480e5c31af7Sopenharmony_ci Vertex3DTextureCase (const Vertex3DTextureCase& other); 1481e5c31af7Sopenharmony_ci Vertex3DTextureCase& operator= (const Vertex3DTextureCase& other); 1482e5c31af7Sopenharmony_ci 1483e5c31af7Sopenharmony_ci float calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const; 1484e5c31af7Sopenharmony_ci void setupShaderInputs (int textureNdx, float lod, const Grid& grid) const; 1485e5c31af7Sopenharmony_ci void renderCell (int textureNdx, float lod, const Grid& grid) const; 1486e5c31af7Sopenharmony_ci void computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const; 1487e5c31af7Sopenharmony_ci 1488e5c31af7Sopenharmony_ci const deUint32 m_minFilter; 1489e5c31af7Sopenharmony_ci const deUint32 m_magFilter; 1490e5c31af7Sopenharmony_ci const deUint32 m_wrapS; 1491e5c31af7Sopenharmony_ci const deUint32 m_wrapT; 1492e5c31af7Sopenharmony_ci const deUint32 m_wrapR; 1493e5c31af7Sopenharmony_ci 1494e5c31af7Sopenharmony_ci const glu::ShaderProgram* m_program; 1495e5c31af7Sopenharmony_ci glu::Texture3D* m_textures[2]; // 2 textures, a gradient texture and a grid texture. 1496e5c31af7Sopenharmony_ci}; 1497e5c31af7Sopenharmony_ci 1498e5c31af7Sopenharmony_ciVertex3DTextureCase::Vertex3DTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR) 1499e5c31af7Sopenharmony_ci : TestCase (testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc) 1500e5c31af7Sopenharmony_ci , m_minFilter (minFilter) 1501e5c31af7Sopenharmony_ci , m_magFilter (magFilter) 1502e5c31af7Sopenharmony_ci , m_wrapS (wrapS) 1503e5c31af7Sopenharmony_ci , m_wrapT (wrapT) 1504e5c31af7Sopenharmony_ci , m_wrapR (wrapR) 1505e5c31af7Sopenharmony_ci , m_program (DE_NULL) 1506e5c31af7Sopenharmony_ci{ 1507e5c31af7Sopenharmony_ci m_textures[0] = DE_NULL; 1508e5c31af7Sopenharmony_ci m_textures[1] = DE_NULL; 1509e5c31af7Sopenharmony_ci} 1510e5c31af7Sopenharmony_ci 1511e5c31af7Sopenharmony_ciVertex3DTextureCase::~Vertex3DTextureCase(void) 1512e5c31af7Sopenharmony_ci{ 1513e5c31af7Sopenharmony_ci Vertex3DTextureCase::deinit(); 1514e5c31af7Sopenharmony_ci} 1515e5c31af7Sopenharmony_ci 1516e5c31af7Sopenharmony_civoid Vertex3DTextureCase::init (void) 1517e5c31af7Sopenharmony_ci{ 1518e5c31af7Sopenharmony_ci const char* const vertexShaderSource = 1519e5c31af7Sopenharmony_ci "#version 300 es\n" 1520e5c31af7Sopenharmony_ci "in highp vec2 a_position;\n" 1521e5c31af7Sopenharmony_ci "in highp vec3 a_texCoord;\n" 1522e5c31af7Sopenharmony_ci "uniform highp sampler3D u_texture;\n" 1523e5c31af7Sopenharmony_ci "uniform highp float u_lod;\n" 1524e5c31af7Sopenharmony_ci "out mediump vec4 v_color;\n" 1525e5c31af7Sopenharmony_ci "\n" 1526e5c31af7Sopenharmony_ci "void main()\n" 1527e5c31af7Sopenharmony_ci "{\n" 1528e5c31af7Sopenharmony_ci " gl_Position = vec4(a_position, 0.0, 1.0);\n" 1529e5c31af7Sopenharmony_ci " v_color = textureLod(u_texture, a_texCoord, u_lod);\n" 1530e5c31af7Sopenharmony_ci "}\n"; 1531e5c31af7Sopenharmony_ci 1532e5c31af7Sopenharmony_ci const char* const fragmentShaderSource = 1533e5c31af7Sopenharmony_ci "#version 300 es\n" 1534e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 dEQP_FragColor;\n" 1535e5c31af7Sopenharmony_ci "in mediump vec4 v_color;\n" 1536e5c31af7Sopenharmony_ci "\n" 1537e5c31af7Sopenharmony_ci "void main()\n" 1538e5c31af7Sopenharmony_ci "{\n" 1539e5c31af7Sopenharmony_ci " dEQP_FragColor = v_color;\n" 1540e5c31af7Sopenharmony_ci "}\n"; 1541e5c31af7Sopenharmony_ci 1542e5c31af7Sopenharmony_ci if (m_context.getRenderTarget().getNumSamples() != 0) 1543e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("MSAA config not supported by this test"); 1544e5c31af7Sopenharmony_ci 1545e5c31af7Sopenharmony_ci // Create shader. 1546e5c31af7Sopenharmony_ci 1547e5c31af7Sopenharmony_ci DE_ASSERT(!m_program); 1548e5c31af7Sopenharmony_ci m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource)); 1549e5c31af7Sopenharmony_ci 1550e5c31af7Sopenharmony_ci if(!m_program->isOk()) 1551e5c31af7Sopenharmony_ci { 1552e5c31af7Sopenharmony_ci m_testCtx.getLog() << *m_program; 1553e5c31af7Sopenharmony_ci 1554e5c31af7Sopenharmony_ci GLint maxVertexTextures; 1555e5c31af7Sopenharmony_ci glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures); 1556e5c31af7Sopenharmony_ci 1557e5c31af7Sopenharmony_ci if (maxVertexTextures < 1) 1558e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__); 1559e5c31af7Sopenharmony_ci else 1560e5c31af7Sopenharmony_ci TCU_FAIL("Failed to compile shader"); 1561e5c31af7Sopenharmony_ci } 1562e5c31af7Sopenharmony_ci 1563e5c31af7Sopenharmony_ci // Make the textures. 1564e5c31af7Sopenharmony_ci 1565e5c31af7Sopenharmony_ci try 1566e5c31af7Sopenharmony_ci { 1567e5c31af7Sopenharmony_ci const int texWidth = WIDTH_3D; 1568e5c31af7Sopenharmony_ci const int texHeight = HEIGHT_3D; 1569e5c31af7Sopenharmony_ci const int texDepth = DEPTH_3D; 1570e5c31af7Sopenharmony_ci 1571e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 1572e5c31af7Sopenharmony_ci { 1573e5c31af7Sopenharmony_ci DE_ASSERT(!m_textures[i]); 1574e5c31af7Sopenharmony_ci m_textures[i] = new glu::Texture3D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight, texDepth); 1575e5c31af7Sopenharmony_ci } 1576e5c31af7Sopenharmony_ci 1577e5c31af7Sopenharmony_ci const int numLevels = deLog2Floor32(de::max(de::max(texWidth, texHeight), texDepth)) + 1; 1578e5c31af7Sopenharmony_ci const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat()); 1579e5c31af7Sopenharmony_ci const Vec4 cBias = fmtInfo.valueMin; 1580e5c31af7Sopenharmony_ci const Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin; 1581e5c31af7Sopenharmony_ci 1582e5c31af7Sopenharmony_ci // Fill first with gradient texture. 1583e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 1584e5c31af7Sopenharmony_ci { 1585e5c31af7Sopenharmony_ci const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias; 1586e5c31af7Sopenharmony_ci const Vec4 gMax = Vec4( 1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias; 1587e5c31af7Sopenharmony_ci 1588e5c31af7Sopenharmony_ci m_textures[0]->getRefTexture().allocLevel(levelNdx); 1589e5c31af7Sopenharmony_ci tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax); 1590e5c31af7Sopenharmony_ci } 1591e5c31af7Sopenharmony_ci 1592e5c31af7Sopenharmony_ci // Fill second with grid texture. 1593e5c31af7Sopenharmony_ci for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 1594e5c31af7Sopenharmony_ci { 1595e5c31af7Sopenharmony_ci const deUint32 step = 0x00ffffff / numLevels; 1596e5c31af7Sopenharmony_ci const deUint32 rgb = step*levelNdx; 1597e5c31af7Sopenharmony_ci const deUint32 colorA = 0xff000000 | rgb; 1598e5c31af7Sopenharmony_ci const deUint32 colorB = 0xff000000 | ~rgb; 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci m_textures[1]->getRefTexture().allocLevel(levelNdx); 1601e5c31af7Sopenharmony_ci tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias); 1602e5c31af7Sopenharmony_ci } 1603e5c31af7Sopenharmony_ci 1604e5c31af7Sopenharmony_ci // Upload. 1605e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 1606e5c31af7Sopenharmony_ci m_textures[i]->upload(); 1607e5c31af7Sopenharmony_ci } 1608e5c31af7Sopenharmony_ci catch (const std::exception&) 1609e5c31af7Sopenharmony_ci { 1610e5c31af7Sopenharmony_ci // Clean up to save memory. 1611e5c31af7Sopenharmony_ci Vertex3DTextureCase::deinit(); 1612e5c31af7Sopenharmony_ci throw; 1613e5c31af7Sopenharmony_ci } 1614e5c31af7Sopenharmony_ci} 1615e5c31af7Sopenharmony_ci 1616e5c31af7Sopenharmony_civoid Vertex3DTextureCase::deinit (void) 1617e5c31af7Sopenharmony_ci{ 1618e5c31af7Sopenharmony_ci for (int i = 0; i < 2; i++) 1619e5c31af7Sopenharmony_ci { 1620e5c31af7Sopenharmony_ci delete m_textures[i]; 1621e5c31af7Sopenharmony_ci m_textures[i] = DE_NULL; 1622e5c31af7Sopenharmony_ci } 1623e5c31af7Sopenharmony_ci 1624e5c31af7Sopenharmony_ci delete m_program; 1625e5c31af7Sopenharmony_ci m_program = DE_NULL; 1626e5c31af7Sopenharmony_ci} 1627e5c31af7Sopenharmony_ci 1628e5c31af7Sopenharmony_cifloat Vertex3DTextureCase::calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const 1629e5c31af7Sopenharmony_ci{ 1630e5c31af7Sopenharmony_ci const tcu::Texture3D& refTexture = m_textures[textureNdx]->getRefTexture(); 1631e5c31af7Sopenharmony_ci const int srcWidth = refTexture.getWidth(); 1632e5c31af7Sopenharmony_ci const int srcHeight = refTexture.getHeight(); 1633e5c31af7Sopenharmony_ci const int srcDepth = refTexture.getDepth(); 1634e5c31af7Sopenharmony_ci 1635e5c31af7Sopenharmony_ci // Calculate transformed coordinates of three screen corners. 1636e5c31af7Sopenharmony_ci const Vec3 trans00 = transf * Vec3(0.0f, 0.0f, 1.0f); 1637e5c31af7Sopenharmony_ci const Vec3 trans01 = transf * Vec3(0.0f, 1.0f, 1.0f); 1638e5c31af7Sopenharmony_ci const Vec3 trans10 = transf * Vec3(1.0f, 0.0f, 1.0f); 1639e5c31af7Sopenharmony_ci 1640e5c31af7Sopenharmony_ci // Derivates. 1641e5c31af7Sopenharmony_ci const float dudx = (trans10.x() - trans00.x()) * (float)srcWidth / dstSize.x(); 1642e5c31af7Sopenharmony_ci const float dudy = (trans01.x() - trans00.x()) * (float)srcWidth / dstSize.y(); 1643e5c31af7Sopenharmony_ci const float dvdx = (trans10.y() - trans00.y()) * (float)srcHeight / dstSize.x(); 1644e5c31af7Sopenharmony_ci const float dvdy = (trans01.y() - trans00.y()) * (float)srcHeight / dstSize.y(); 1645e5c31af7Sopenharmony_ci const float dwdx = (trans10.z() - trans00.z()) * (float)srcDepth / dstSize.x(); 1646e5c31af7Sopenharmony_ci const float dwdy = (trans01.z() - trans00.z()) * (float)srcDepth / dstSize.y(); 1647e5c31af7Sopenharmony_ci 1648e5c31af7Sopenharmony_ci return deFloatLog2(deFloatSqrt(de::max(dudx*dudx + dvdx*dvdx + dwdx*dwdx, dudy*dudy + dvdy*dvdy + dwdy*dwdy))); 1649e5c31af7Sopenharmony_ci} 1650e5c31af7Sopenharmony_ci 1651e5c31af7Sopenharmony_ciVertex3DTextureCase::IterateResult Vertex3DTextureCase::iterate (void) 1652e5c31af7Sopenharmony_ci{ 1653e5c31af7Sopenharmony_ci const int viewportWidth = deMin32(m_context.getRenderTarget().getWidth(), MAX_3D_RENDER_WIDTH); 1654e5c31af7Sopenharmony_ci const int viewportHeight = deMin32(m_context.getRenderTarget().getHeight(), MAX_3D_RENDER_HEIGHT); 1655e5c31af7Sopenharmony_ci 1656e5c31af7Sopenharmony_ci const int viewportXOffsetMax = m_context.getRenderTarget().getWidth() - viewportWidth; 1657e5c31af7Sopenharmony_ci const int viewportYOffsetMax = m_context.getRenderTarget().getHeight() - viewportHeight; 1658e5c31af7Sopenharmony_ci 1659e5c31af7Sopenharmony_ci de::Random rnd (deStringHash(getName())); 1660e5c31af7Sopenharmony_ci 1661e5c31af7Sopenharmony_ci const int viewportXOffset = rnd.getInt(0, viewportXOffsetMax); 1662e5c31af7Sopenharmony_ci const int viewportYOffset = rnd.getInt(0, viewportYOffsetMax); 1663e5c31af7Sopenharmony_ci 1664e5c31af7Sopenharmony_ci glUseProgram(m_program->getProgram()); 1665e5c31af7Sopenharmony_ci 1666e5c31af7Sopenharmony_ci // Divide viewport into 4 cells. 1667e5c31af7Sopenharmony_ci const int leftWidth = viewportWidth / 2; 1668e5c31af7Sopenharmony_ci const int rightWidth = viewportWidth - leftWidth; 1669e5c31af7Sopenharmony_ci const int bottomHeight = viewportHeight / 2; 1670e5c31af7Sopenharmony_ci const int topHeight = viewportHeight - bottomHeight; 1671e5c31af7Sopenharmony_ci 1672e5c31af7Sopenharmony_ci // Clear. 1673e5c31af7Sopenharmony_ci glClearColor(0.125f, 0.25f, 0.5f, 1.0f); 1674e5c31af7Sopenharmony_ci glClear(GL_COLOR_BUFFER_BIT); 1675e5c31af7Sopenharmony_ci 1676e5c31af7Sopenharmony_ci // Shear to get all slices visible. 1677e5c31af7Sopenharmony_ci static const float depthShearTransfData[] = 1678e5c31af7Sopenharmony_ci { 1679e5c31af7Sopenharmony_ci 1.0f, 0.0f, 0.0f, 1680e5c31af7Sopenharmony_ci 0.0f, 1.0f, 0.0f, 1681e5c31af7Sopenharmony_ci 1.0f, 1.0f, 0.0f 1682e5c31af7Sopenharmony_ci }; 1683e5c31af7Sopenharmony_ci 1684e5c31af7Sopenharmony_ci // Minification and magnification transformations. 1685e5c31af7Sopenharmony_ci static const float texMinTransfData[] = 1686e5c31af7Sopenharmony_ci { 1687e5c31af7Sopenharmony_ci 2.2f, 0.0f, -0.3f, 1688e5c31af7Sopenharmony_ci 0.0f, 2.2f, -0.3f, 1689e5c31af7Sopenharmony_ci 0.0f, 0.0f, 1.0f 1690e5c31af7Sopenharmony_ci }; 1691e5c31af7Sopenharmony_ci static const float texMagTransfData[] = 1692e5c31af7Sopenharmony_ci { 1693e5c31af7Sopenharmony_ci 0.4f, 0.0f, 0.8f, 1694e5c31af7Sopenharmony_ci 0.0f, 0.4f, 0.8f, 1695e5c31af7Sopenharmony_ci 0.0f, 0.0f, 1.0f 1696e5c31af7Sopenharmony_ci }; 1697e5c31af7Sopenharmony_ci 1698e5c31af7Sopenharmony_ci // Transformation matrices for minification and magnification. 1699e5c31af7Sopenharmony_ci const Mat3 texMinTransf = Mat3(depthShearTransfData) * Mat3(texMinTransfData); 1700e5c31af7Sopenharmony_ci const Mat3 texMagTransf = Mat3(depthShearTransfData) * Mat3(texMagTransfData); 1701e5c31af7Sopenharmony_ci 1702e5c31af7Sopenharmony_ci // Surface for the reference image. 1703e5c31af7Sopenharmony_ci tcu::Surface refImage(viewportWidth, viewportHeight); 1704e5c31af7Sopenharmony_ci 1705e5c31af7Sopenharmony_ci { 1706e5c31af7Sopenharmony_ci const struct Render 1707e5c31af7Sopenharmony_ci { 1708e5c31af7Sopenharmony_ci const Rect region; 1709e5c31af7Sopenharmony_ci int textureNdx; 1710e5c31af7Sopenharmony_ci const Mat3 texTransform; 1711e5c31af7Sopenharmony_ci Render (const Rect& r, int tN, const Mat3& tT) : region(r), textureNdx(tN), texTransform(tT) {} 1712e5c31af7Sopenharmony_ci } renders[] = 1713e5c31af7Sopenharmony_ci { 1714e5c31af7Sopenharmony_ci Render(Rect(0, 0, leftWidth, bottomHeight), 0, texMinTransf), 1715e5c31af7Sopenharmony_ci Render(Rect(leftWidth, 0, rightWidth, bottomHeight), 0, texMagTransf), 1716e5c31af7Sopenharmony_ci Render(Rect(0, bottomHeight, leftWidth, topHeight), 1, texMinTransf), 1717e5c31af7Sopenharmony_ci Render(Rect(leftWidth, bottomHeight, rightWidth, topHeight), 1, texMagTransf) 1718e5c31af7Sopenharmony_ci }; 1719e5c31af7Sopenharmony_ci 1720e5c31af7Sopenharmony_ci for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++) 1721e5c31af7Sopenharmony_ci { 1722e5c31af7Sopenharmony_ci const Render& rend = renders[renderNdx]; 1723e5c31af7Sopenharmony_ci const float lod = calculateLod(rend.texTransform, rend.region.size().asFloat(), rend.textureNdx); 1724e5c31af7Sopenharmony_ci const bool useSafeTexCoords = isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter); 1725e5c31af7Sopenharmony_ci const Grid grid (GRID_SIZE_3D, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]), 1726e5c31af7Sopenharmony_ci TexTypeCoordParams<TEXTURETYPE_3D>(rend.texTransform), useSafeTexCoords); 1727e5c31af7Sopenharmony_ci 1728e5c31af7Sopenharmony_ci glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h); 1729e5c31af7Sopenharmony_ci renderCell (rend.textureNdx, lod, grid); 1730e5c31af7Sopenharmony_ci computeReferenceCell (rend.textureNdx, lod, grid, refImage, rend.region); 1731e5c31af7Sopenharmony_ci } 1732e5c31af7Sopenharmony_ci } 1733e5c31af7Sopenharmony_ci 1734e5c31af7Sopenharmony_ci // Read back rendered results. 1735e5c31af7Sopenharmony_ci tcu::Surface resImage(viewportWidth, viewportHeight); 1736e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess()); 1737e5c31af7Sopenharmony_ci 1738e5c31af7Sopenharmony_ci glUseProgram(0); 1739e5c31af7Sopenharmony_ci 1740e5c31af7Sopenharmony_ci // Compare and log. 1741e5c31af7Sopenharmony_ci { 1742e5c31af7Sopenharmony_ci const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage); 1743e5c31af7Sopenharmony_ci 1744e5c31af7Sopenharmony_ci m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 1745e5c31af7Sopenharmony_ci isOk ? "Pass" : "Image comparison failed"); 1746e5c31af7Sopenharmony_ci } 1747e5c31af7Sopenharmony_ci 1748e5c31af7Sopenharmony_ci return STOP; 1749e5c31af7Sopenharmony_ci} 1750e5c31af7Sopenharmony_ci 1751e5c31af7Sopenharmony_civoid Vertex3DTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const 1752e5c31af7Sopenharmony_ci{ 1753e5c31af7Sopenharmony_ci const deUint32 programID = m_program->getProgram(); 1754e5c31af7Sopenharmony_ci 1755e5c31af7Sopenharmony_ci // SETUP ATTRIBUTES. 1756e5c31af7Sopenharmony_ci 1757e5c31af7Sopenharmony_ci { 1758e5c31af7Sopenharmony_ci const int positionLoc = glGetAttribLocation(programID, "a_position"); 1759e5c31af7Sopenharmony_ci if (positionLoc != -1) 1760e5c31af7Sopenharmony_ci { 1761e5c31af7Sopenharmony_ci glEnableVertexAttribArray(positionLoc); 1762e5c31af7Sopenharmony_ci glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr()); 1763e5c31af7Sopenharmony_ci } 1764e5c31af7Sopenharmony_ci } 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci { 1767e5c31af7Sopenharmony_ci const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord"); 1768e5c31af7Sopenharmony_ci if (texCoordLoc != -1) 1769e5c31af7Sopenharmony_ci { 1770e5c31af7Sopenharmony_ci glEnableVertexAttribArray(texCoordLoc); 1771e5c31af7Sopenharmony_ci glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr()); 1772e5c31af7Sopenharmony_ci } 1773e5c31af7Sopenharmony_ci } 1774e5c31af7Sopenharmony_ci 1775e5c31af7Sopenharmony_ci // SETUP UNIFORMS. 1776e5c31af7Sopenharmony_ci 1777e5c31af7Sopenharmony_ci { 1778e5c31af7Sopenharmony_ci const int lodLoc = glGetUniformLocation(programID, "u_lod"); 1779e5c31af7Sopenharmony_ci if (lodLoc != -1) 1780e5c31af7Sopenharmony_ci glUniform1f(lodLoc, lod); 1781e5c31af7Sopenharmony_ci } 1782e5c31af7Sopenharmony_ci 1783e5c31af7Sopenharmony_ci glActiveTexture(GL_TEXTURE0); 1784e5c31af7Sopenharmony_ci glBindTexture(GL_TEXTURE_3D, m_textures[textureNdx]->getGLTexture()); 1785e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, m_wrapS); 1786e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, m_wrapT); 1787e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, m_wrapR); 1788e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, m_minFilter); 1789e5c31af7Sopenharmony_ci glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, m_magFilter); 1790e5c31af7Sopenharmony_ci 1791e5c31af7Sopenharmony_ci { 1792e5c31af7Sopenharmony_ci const int texLoc = glGetUniformLocation(programID, "u_texture"); 1793e5c31af7Sopenharmony_ci if (texLoc != -1) 1794e5c31af7Sopenharmony_ci glUniform1i(texLoc, 0); 1795e5c31af7Sopenharmony_ci } 1796e5c31af7Sopenharmony_ci} 1797e5c31af7Sopenharmony_ci 1798e5c31af7Sopenharmony_ci// Renders one sub-image with given parameters. 1799e5c31af7Sopenharmony_civoid Vertex3DTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const 1800e5c31af7Sopenharmony_ci{ 1801e5c31af7Sopenharmony_ci setupShaderInputs(textureNdx, lod, grid); 1802e5c31af7Sopenharmony_ci glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr()); 1803e5c31af7Sopenharmony_ci} 1804e5c31af7Sopenharmony_ci 1805e5c31af7Sopenharmony_ci// Computes reference for one sub-image with given parameters. 1806e5c31af7Sopenharmony_civoid Vertex3DTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const 1807e5c31af7Sopenharmony_ci{ 1808e5c31af7Sopenharmony_ci computeReference(m_textures[textureNdx]->getRefTexture(), lod, glu::mapGLSampler(m_wrapS, m_wrapT, m_wrapR, m_minFilter, m_magFilter), grid, dst, dstRegion); 1809e5c31af7Sopenharmony_ci} 1810e5c31af7Sopenharmony_ci 1811e5c31af7Sopenharmony_ciVertexTextureTests::VertexTextureTests (Context& context) 1812e5c31af7Sopenharmony_ci : TestCaseGroup(context, "vertex", "Vertex Texture Tests") 1813e5c31af7Sopenharmony_ci{ 1814e5c31af7Sopenharmony_ci} 1815e5c31af7Sopenharmony_ci 1816e5c31af7Sopenharmony_ciVertexTextureTests::~VertexTextureTests(void) 1817e5c31af7Sopenharmony_ci{ 1818e5c31af7Sopenharmony_ci} 1819e5c31af7Sopenharmony_ci 1820e5c31af7Sopenharmony_civoid VertexTextureTests::init (void) 1821e5c31af7Sopenharmony_ci{ 1822e5c31af7Sopenharmony_ci // 2D and cube map groups, and their filtering and wrap sub-groups. 1823e5c31af7Sopenharmony_ci TestCaseGroup* const group2D = new TestCaseGroup(m_context, "2d", "2D Vertex Texture Tests"); 1824e5c31af7Sopenharmony_ci TestCaseGroup* const groupCube = new TestCaseGroup(m_context, "cube", "Cube Map Vertex Texture Tests"); 1825e5c31af7Sopenharmony_ci TestCaseGroup* const group2DArray = new TestCaseGroup(m_context, "2d_array", "2D Array Vertex Texture Tests"); 1826e5c31af7Sopenharmony_ci TestCaseGroup* const group3D = new TestCaseGroup(m_context, "3d", "3D Vertex Texture Tests"); 1827e5c31af7Sopenharmony_ci TestCaseGroup* const filteringGroup2D = new TestCaseGroup(m_context, "filtering", "2D Vertex Texture Filtering Tests"); 1828e5c31af7Sopenharmony_ci TestCaseGroup* const wrapGroup2D = new TestCaseGroup(m_context, "wrap", "2D Vertex Texture Wrap Tests"); 1829e5c31af7Sopenharmony_ci TestCaseGroup* const filteringGroupCube = new TestCaseGroup(m_context, "filtering", "Cube Map Vertex Texture Filtering Tests"); 1830e5c31af7Sopenharmony_ci TestCaseGroup* const wrapGroupCube = new TestCaseGroup(m_context, "wrap", "Cube Map Vertex Texture Wrap Tests"); 1831e5c31af7Sopenharmony_ci TestCaseGroup* const filteringGroup2DArray = new TestCaseGroup(m_context, "filtering", "2D Array Vertex Texture Filtering Tests"); 1832e5c31af7Sopenharmony_ci TestCaseGroup* const wrapGroup2DArray = new TestCaseGroup(m_context, "wrap", "2D Array Vertex Texture Wrap Tests"); 1833e5c31af7Sopenharmony_ci TestCaseGroup* const filteringGroup3D = new TestCaseGroup(m_context, "filtering", "3D Vertex Texture Filtering Tests"); 1834e5c31af7Sopenharmony_ci TestCaseGroup* const wrapGroup3D = new TestCaseGroup(m_context, "wrap", "3D Vertex Texture Wrap Tests"); 1835e5c31af7Sopenharmony_ci 1836e5c31af7Sopenharmony_ci group2D->addChild(filteringGroup2D); 1837e5c31af7Sopenharmony_ci group2D->addChild(wrapGroup2D); 1838e5c31af7Sopenharmony_ci groupCube->addChild(filteringGroupCube); 1839e5c31af7Sopenharmony_ci groupCube->addChild(wrapGroupCube); 1840e5c31af7Sopenharmony_ci group2DArray->addChild(filteringGroup2DArray); 1841e5c31af7Sopenharmony_ci group2DArray->addChild(wrapGroup2DArray); 1842e5c31af7Sopenharmony_ci group3D->addChild(filteringGroup3D); 1843e5c31af7Sopenharmony_ci group3D->addChild(wrapGroup3D); 1844e5c31af7Sopenharmony_ci 1845e5c31af7Sopenharmony_ci addChild(group2D); 1846e5c31af7Sopenharmony_ci addChild(groupCube); 1847e5c31af7Sopenharmony_ci addChild(group2DArray); 1848e5c31af7Sopenharmony_ci addChild(group3D); 1849e5c31af7Sopenharmony_ci 1850e5c31af7Sopenharmony_ci static const struct 1851e5c31af7Sopenharmony_ci { 1852e5c31af7Sopenharmony_ci const char* name; 1853e5c31af7Sopenharmony_ci GLenum mode; 1854e5c31af7Sopenharmony_ci } wrapModes[] = 1855e5c31af7Sopenharmony_ci { 1856e5c31af7Sopenharmony_ci { "clamp", GL_CLAMP_TO_EDGE }, 1857e5c31af7Sopenharmony_ci { "repeat", GL_REPEAT }, 1858e5c31af7Sopenharmony_ci { "mirror", GL_MIRRORED_REPEAT } 1859e5c31af7Sopenharmony_ci }; 1860e5c31af7Sopenharmony_ci 1861e5c31af7Sopenharmony_ci static const struct 1862e5c31af7Sopenharmony_ci { 1863e5c31af7Sopenharmony_ci const char* name; 1864e5c31af7Sopenharmony_ci GLenum mode; 1865e5c31af7Sopenharmony_ci } minFilterModes[] = 1866e5c31af7Sopenharmony_ci { 1867e5c31af7Sopenharmony_ci { "nearest", GL_NEAREST }, 1868e5c31af7Sopenharmony_ci { "linear", GL_LINEAR }, 1869e5c31af7Sopenharmony_ci { "nearest_mipmap_nearest", GL_NEAREST_MIPMAP_NEAREST }, 1870e5c31af7Sopenharmony_ci { "linear_mipmap_nearest", GL_LINEAR_MIPMAP_NEAREST }, 1871e5c31af7Sopenharmony_ci { "nearest_mipmap_linear", GL_NEAREST_MIPMAP_LINEAR }, 1872e5c31af7Sopenharmony_ci { "linear_mipmap_linear", GL_LINEAR_MIPMAP_LINEAR } 1873e5c31af7Sopenharmony_ci }; 1874e5c31af7Sopenharmony_ci 1875e5c31af7Sopenharmony_ci static const struct 1876e5c31af7Sopenharmony_ci { 1877e5c31af7Sopenharmony_ci const char* name; 1878e5c31af7Sopenharmony_ci GLenum mode; 1879e5c31af7Sopenharmony_ci } magFilterModes[] = 1880e5c31af7Sopenharmony_ci { 1881e5c31af7Sopenharmony_ci { "nearest", GL_NEAREST }, 1882e5c31af7Sopenharmony_ci { "linear", GL_LINEAR } 1883e5c31af7Sopenharmony_ci }; 1884e5c31af7Sopenharmony_ci 1885e5c31af7Sopenharmony_ci#define FOR_EACH(ITERATOR, ARRAY, BODY) \ 1886e5c31af7Sopenharmony_ci for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++) \ 1887e5c31af7Sopenharmony_ci BODY 1888e5c31af7Sopenharmony_ci 1889e5c31af7Sopenharmony_ci // 2D cases. 1890e5c31af7Sopenharmony_ci 1891e5c31af7Sopenharmony_ci FOR_EACH(minFilter, minFilterModes, 1892e5c31af7Sopenharmony_ci FOR_EACH(magFilter, magFilterModes, 1893e5c31af7Sopenharmony_ci FOR_EACH(wrapMode, wrapModes, 1894e5c31af7Sopenharmony_ci { 1895e5c31af7Sopenharmony_ci const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name; 1896e5c31af7Sopenharmony_ci 1897e5c31af7Sopenharmony_ci filteringGroup2D->addChild(new Vertex2DTextureCase(m_context, 1898e5c31af7Sopenharmony_ci name.c_str(), "", 1899e5c31af7Sopenharmony_ci minFilterModes[minFilter].mode, 1900e5c31af7Sopenharmony_ci magFilterModes[magFilter].mode, 1901e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode, 1902e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode)); 1903e5c31af7Sopenharmony_ci }))) 1904e5c31af7Sopenharmony_ci 1905e5c31af7Sopenharmony_ci FOR_EACH(wrapSMode, wrapModes, 1906e5c31af7Sopenharmony_ci FOR_EACH(wrapTMode, wrapModes, 1907e5c31af7Sopenharmony_ci { 1908e5c31af7Sopenharmony_ci const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name; 1909e5c31af7Sopenharmony_ci 1910e5c31af7Sopenharmony_ci wrapGroup2D->addChild(new Vertex2DTextureCase(m_context, 1911e5c31af7Sopenharmony_ci name.c_str(), "", 1912e5c31af7Sopenharmony_ci GL_LINEAR_MIPMAP_LINEAR, 1913e5c31af7Sopenharmony_ci GL_LINEAR, 1914e5c31af7Sopenharmony_ci wrapModes[wrapSMode].mode, 1915e5c31af7Sopenharmony_ci wrapModes[wrapTMode].mode)); 1916e5c31af7Sopenharmony_ci })) 1917e5c31af7Sopenharmony_ci 1918e5c31af7Sopenharmony_ci // Cube map cases. 1919e5c31af7Sopenharmony_ci 1920e5c31af7Sopenharmony_ci FOR_EACH(minFilter, minFilterModes, 1921e5c31af7Sopenharmony_ci FOR_EACH(magFilter, magFilterModes, 1922e5c31af7Sopenharmony_ci FOR_EACH(wrapMode, wrapModes, 1923e5c31af7Sopenharmony_ci { 1924e5c31af7Sopenharmony_ci const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name; 1925e5c31af7Sopenharmony_ci 1926e5c31af7Sopenharmony_ci filteringGroupCube->addChild(new VertexCubeTextureCase(m_context, 1927e5c31af7Sopenharmony_ci name.c_str(), "", 1928e5c31af7Sopenharmony_ci minFilterModes[minFilter].mode, 1929e5c31af7Sopenharmony_ci magFilterModes[magFilter].mode, 1930e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode, 1931e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode)); 1932e5c31af7Sopenharmony_ci }))) 1933e5c31af7Sopenharmony_ci 1934e5c31af7Sopenharmony_ci FOR_EACH(wrapSMode, wrapModes, 1935e5c31af7Sopenharmony_ci FOR_EACH(wrapTMode, wrapModes, 1936e5c31af7Sopenharmony_ci { 1937e5c31af7Sopenharmony_ci const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name; 1938e5c31af7Sopenharmony_ci 1939e5c31af7Sopenharmony_ci wrapGroupCube->addChild(new VertexCubeTextureCase(m_context, 1940e5c31af7Sopenharmony_ci name.c_str(), "", 1941e5c31af7Sopenharmony_ci GL_LINEAR_MIPMAP_LINEAR, 1942e5c31af7Sopenharmony_ci GL_LINEAR, 1943e5c31af7Sopenharmony_ci wrapModes[wrapSMode].mode, 1944e5c31af7Sopenharmony_ci wrapModes[wrapTMode].mode)); 1945e5c31af7Sopenharmony_ci })) 1946e5c31af7Sopenharmony_ci 1947e5c31af7Sopenharmony_ci // 2D array cases. 1948e5c31af7Sopenharmony_ci 1949e5c31af7Sopenharmony_ci FOR_EACH(minFilter, minFilterModes, 1950e5c31af7Sopenharmony_ci FOR_EACH(magFilter, magFilterModes, 1951e5c31af7Sopenharmony_ci FOR_EACH(wrapMode, wrapModes, 1952e5c31af7Sopenharmony_ci { 1953e5c31af7Sopenharmony_ci const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name; 1954e5c31af7Sopenharmony_ci 1955e5c31af7Sopenharmony_ci filteringGroup2DArray->addChild(new Vertex2DArrayTextureCase(m_context, 1956e5c31af7Sopenharmony_ci name.c_str(), "", 1957e5c31af7Sopenharmony_ci minFilterModes[minFilter].mode, 1958e5c31af7Sopenharmony_ci magFilterModes[magFilter].mode, 1959e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode, 1960e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode)); 1961e5c31af7Sopenharmony_ci }))) 1962e5c31af7Sopenharmony_ci 1963e5c31af7Sopenharmony_ci FOR_EACH(wrapSMode, wrapModes, 1964e5c31af7Sopenharmony_ci FOR_EACH(wrapTMode, wrapModes, 1965e5c31af7Sopenharmony_ci { 1966e5c31af7Sopenharmony_ci const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name; 1967e5c31af7Sopenharmony_ci 1968e5c31af7Sopenharmony_ci wrapGroup2DArray->addChild(new Vertex2DArrayTextureCase(m_context, 1969e5c31af7Sopenharmony_ci name.c_str(), "", 1970e5c31af7Sopenharmony_ci GL_LINEAR_MIPMAP_LINEAR, 1971e5c31af7Sopenharmony_ci GL_LINEAR, 1972e5c31af7Sopenharmony_ci wrapModes[wrapSMode].mode, 1973e5c31af7Sopenharmony_ci wrapModes[wrapTMode].mode)); 1974e5c31af7Sopenharmony_ci })) 1975e5c31af7Sopenharmony_ci 1976e5c31af7Sopenharmony_ci // 3D cases. 1977e5c31af7Sopenharmony_ci 1978e5c31af7Sopenharmony_ci FOR_EACH(minFilter, minFilterModes, 1979e5c31af7Sopenharmony_ci FOR_EACH(magFilter, magFilterModes, 1980e5c31af7Sopenharmony_ci FOR_EACH(wrapMode, wrapModes, 1981e5c31af7Sopenharmony_ci { 1982e5c31af7Sopenharmony_ci const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name; 1983e5c31af7Sopenharmony_ci 1984e5c31af7Sopenharmony_ci filteringGroup3D->addChild(new Vertex3DTextureCase(m_context, 1985e5c31af7Sopenharmony_ci name.c_str(), "", 1986e5c31af7Sopenharmony_ci minFilterModes[minFilter].mode, 1987e5c31af7Sopenharmony_ci magFilterModes[magFilter].mode, 1988e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode, 1989e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode, 1990e5c31af7Sopenharmony_ci wrapModes[wrapMode].mode)); 1991e5c31af7Sopenharmony_ci }))) 1992e5c31af7Sopenharmony_ci 1993e5c31af7Sopenharmony_ci FOR_EACH(wrapSMode, wrapModes, 1994e5c31af7Sopenharmony_ci FOR_EACH(wrapTMode, wrapModes, 1995e5c31af7Sopenharmony_ci FOR_EACH(wrapRMode, wrapModes, 1996e5c31af7Sopenharmony_ci { 1997e5c31af7Sopenharmony_ci const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name + "_" + wrapModes[wrapRMode].name; 1998e5c31af7Sopenharmony_ci 1999e5c31af7Sopenharmony_ci wrapGroup3D->addChild(new Vertex3DTextureCase(m_context, 2000e5c31af7Sopenharmony_ci name.c_str(), "", 2001e5c31af7Sopenharmony_ci GL_LINEAR_MIPMAP_LINEAR, 2002e5c31af7Sopenharmony_ci GL_LINEAR, 2003e5c31af7Sopenharmony_ci wrapModes[wrapSMode].mode, 2004e5c31af7Sopenharmony_ci wrapModes[wrapTMode].mode, 2005e5c31af7Sopenharmony_ci wrapModes[wrapRMode].mode)); 2006e5c31af7Sopenharmony_ci }))) 2007e5c31af7Sopenharmony_ci} 2008e5c31af7Sopenharmony_ci 2009e5c31af7Sopenharmony_ci} // Functional 2010e5c31af7Sopenharmony_ci} // gles3 2011e5c31af7Sopenharmony_ci} // deqp 2012