1c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket/*------------------------------------------------------------------------- 2c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * drawElements Quality Program OpenGL ES Utilities 3c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * ------------------------------------------------ 4c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * 5c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * Copyright 2014 The Android Open Source Project 6c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * 7c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * Licensed under the Apache License, Version 2.0 (the "License"); 8c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * you may not use this file except in compliance with the License. 9c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * You may obtain a copy of the License at 10c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * 11c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * http://www.apache.org/licenses/LICENSE-2.0 12c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * 13c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * Unless required by applicable law or agreed to in writing, software 14c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * distributed under the License is distributed on an "AS IS" BASIS, 15c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * See the License for the specific language governing permissions and 17c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * limitations under the License. 18c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * 19c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket *//*! 20c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * \file 21c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * \brief Utility functions and structures for texture tests. This code 22c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * is originated from the modules/glshared/glsTextureTestUtil.hpp and it 23c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket * is tightly coupled with the GLES and Vulkan texture tests! 24c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket *//*--------------------------------------------------------------------*/ 25c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 26c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include "gluTextureTestUtil.hpp" 27c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 28c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include "tcuFloat.hpp" 29c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include "tcuImageCompare.hpp" 30c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include "tcuTestLog.hpp" 31c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include "tcuVectorUtil.hpp" 32c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 33c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include "deMath.h" 34c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include "deStringUtil.hpp" 35c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 36c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket#include <string> 37c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 38c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketusing std::string; 39c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 40c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketnamespace glu 41c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 42c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 43c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketnamespace TextureTestUtil 44c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 45c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 46c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketenum 47c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 48c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket MIN_SUBPIXEL_BITS = 4 49c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket}; 50c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 51c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter SiketSamplerType getSamplerType (tcu::TextureFormat format) 52c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 53c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket using tcu::TextureFormat; 54c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 55c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (format.type) 56c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 57c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::SIGNED_INT8: 58c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::SIGNED_INT16: 59c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::SIGNED_INT32: 60c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return SAMPLERTYPE_INT; 61c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 62c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT8: 63c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT32: 64c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT_1010102_REV: 65c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return SAMPLERTYPE_UINT; 66c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 67c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Texture formats used in depth/stencil textures. 68c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT16: 69c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT_24_8: 70c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return (format.order == TextureFormat::D || format.order == TextureFormat::DS) ? SAMPLERTYPE_FLOAT : SAMPLERTYPE_UINT; 71c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 72c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 73c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return SAMPLERTYPE_FLOAT; 74c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 75c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 76c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 77c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter SiketSamplerType getFetchSamplerType (tcu::TextureFormat format) 78c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 79c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket using tcu::TextureFormat; 80c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 81c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (format.type) 82c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 83c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::SIGNED_INT8: 84c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::SIGNED_INT16: 85c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::SIGNED_INT32: 86c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return SAMPLERTYPE_FETCH_INT; 87c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 88c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT8: 89c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT32: 90c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT_1010102_REV: 91c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return SAMPLERTYPE_FETCH_UINT; 92c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 93c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Texture formats used in depth/stencil textures. 94c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT16: 95c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case TextureFormat::UNSIGNED_INT_24_8: 96c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return (format.order == TextureFormat::D || format.order == TextureFormat::DS) ? SAMPLERTYPE_FETCH_FLOAT : SAMPLERTYPE_FETCH_UINT; 97c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 98c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 99c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return SAMPLERTYPE_FETCH_FLOAT; 100c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 101c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 102c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 103c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic tcu::Texture1DView getSubView (const tcu::Texture1DView& view, int baseLevel, int maxLevel) 104c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 105c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels()-1); 106c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedMax = de::clamp(maxLevel, clampedBase, view.getNumLevels()-1); 107c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numLevels = clampedMax-clampedBase+1; 108c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Texture1DView(numLevels, view.getLevels()+clampedBase); 109c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 110c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 111c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic tcu::Texture2DView getSubView (const tcu::Texture2DView& view, int baseLevel, int maxLevel) 112c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 113c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels()-1); 114c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedMax = de::clamp(maxLevel, clampedBase, view.getNumLevels()-1); 115c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numLevels = clampedMax-clampedBase+1; 116c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Texture2DView(numLevels, view.getLevels()+clampedBase); 117c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 118c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 119c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic tcu::TextureCubeView getSubView (const tcu::TextureCubeView& view, int baseLevel, int maxLevel) 120c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 121c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels()-1); 122c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedMax = de::clamp(maxLevel, clampedBase, view.getNumLevels()-1); 123c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numLevels = clampedMax-clampedBase+1; 124c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess* levels[tcu::CUBEFACE_LAST]; 125c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 126c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int face = 0; face < tcu::CUBEFACE_LAST; face++) 127c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levels[face] = view.getFaceLevels((tcu::CubeFace)face) + clampedBase; 128c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 129c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::TextureCubeView(numLevels, levels); 130c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 131c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 132c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic tcu::Texture3DView getSubView (const tcu::Texture3DView& view, int baseLevel, int maxLevel) 133c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 134c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels()-1); 135c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedMax = de::clamp(maxLevel, clampedBase, view.getNumLevels()-1); 136c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numLevels = clampedMax-clampedBase+1; 137c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Texture3DView(numLevels, view.getLevels()+clampedBase); 138c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 139c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 140c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic tcu::TextureCubeArrayView getSubView (const tcu::TextureCubeArrayView& view, int baseLevel, int maxLevel) 141c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 142c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels()-1); 143c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int clampedMax = de::clamp(maxLevel, clampedBase, view.getNumLevels()-1); 144c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numLevels = clampedMax-clampedBase+1; 145c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::TextureCubeArrayView(numLevels, view.getLevels()+clampedBase); 146c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 147c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 148c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline float linearInterpolate (float t, float minVal, float maxVal) 149c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 150c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return minVal + (maxVal - minVal) * t; 151c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 152c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 153c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline tcu::Vec4 linearInterpolate (float t, const tcu::Vec4& a, const tcu::Vec4& b) 154c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 155c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return a + (b - a) * t; 156c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 157c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 158c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline float bilinearInterpolate (float x, float y, const tcu::Vec4& quad) 159c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 160c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float w00 = (1.0f-x)*(1.0f-y); 161c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float w01 = (1.0f-x)*y; 162c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float w10 = x*(1.0f-y); 163c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float w11 = x*y; 164c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return quad.x()*w00 + quad.y()*w10 + quad.z()*w01 + quad.w()*w11; 165c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 166c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 167c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline float triangleInterpolate (float v0, float v1, float v2, float x, float y) 168c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 169c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return v0 + (v2-v0)*x + (v1-v0)*y; 170c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 171c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 172c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline float triangleInterpolate (const tcu::Vec3& v, float x, float y) 173c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 174c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return triangleInterpolate(v.x(), v.y(), v.z(), x, y); 175c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 176c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 177c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// 1D lookup LOD computation. 178c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 179c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketfloat computeLodFromDerivates (LodMode mode, float dudx, float dudy) 180c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 181c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float p = 0.0f; 182c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (mode) 183c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 184c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // \note [mika] Min and max bounds equal to exact with 1D textures 185c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_EXACT: 186c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_MIN_BOUND: 187c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_MAX_BOUND: 188c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket p = de::max(deFloatAbs(dudx), deFloatAbs(dudy)); 189c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 190c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 191c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 192c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(DE_FALSE); 193c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 194c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 195c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return deFloatLog2(p); 196c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 197c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 198c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic float computeNonProjectedTriLod (LodMode mode, const tcu::IVec2& dstSize, deInt32 srcSize, const tcu::Vec3& sq) 199c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 200c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dux = (sq.z() - sq.x()) * (float)srcSize; 201c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float duy = (sq.y() - sq.x()) * (float)srcSize; 202c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dx = (float)dstSize.x(); 203c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dy = (float)dstSize.y(); 204c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 205c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return computeLodFromDerivates(mode, dux/dx, duy/dy); 206c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 207c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 208c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// 2D lookup LOD computation. 209c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 210c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketfloat computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dudy, float dvdy) 211c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 212c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float p = 0.0f; 213c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (mode) 214c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 215c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_EXACT: 216c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx), deFloatSqrt(dudy*dudy + dvdy*dvdy)); 217c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 218c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 219c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_MIN_BOUND: 220c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_MAX_BOUND: 221c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 222c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy)); 223c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy)); 224c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 225c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv; 226c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 227c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 228c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 229c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 230c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(DE_FALSE); 231c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 232c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 233c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return deFloatLog2(p); 234c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 235c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 236c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic float computeNonProjectedTriLod (LodMode mode, const tcu::IVec2& dstSize, const tcu::IVec2& srcSize, const tcu::Vec3& sq, const tcu::Vec3& tq) 237c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 238c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dux = (sq.z() - sq.x()) * (float)srcSize.x(); 239c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float duy = (sq.y() - sq.x()) * (float)srcSize.x(); 240c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvx = (tq.z() - tq.x()) * (float)srcSize.y(); 241c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvy = (tq.y() - tq.x()) * (float)srcSize.y(); 242c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dx = (float)dstSize.x(); 243c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dy = (float)dstSize.y(); 244c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 245c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return computeLodFromDerivates(mode, dux/dx, dvx/dx, duy/dy, dvy/dy); 246c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 247c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 248c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// 3D lookup LOD computation. 249c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 250c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketfloat computeLodFromDerivates (LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy) 251c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 252c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float p = 0.0f; 253c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (mode) 254c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 255c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_EXACT: 256c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket p = de::max(deFloatSqrt(dudx*dudx + dvdx*dvdx + dwdx*dwdx), deFloatSqrt(dudy*dudy + dvdy*dvdy + dwdy*dwdy)); 257c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 258c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 259c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_MIN_BOUND: 260c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case LODMODE_MAX_BOUND: 261c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 262c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy)); 263c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy)); 264c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy)); 265c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 266c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw); 267c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 268c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 269c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 270c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 271c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(DE_FALSE); 272c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 273c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 274c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return deFloatLog2(p); 275c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 276c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 277c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic float computeNonProjectedTriLod (LodMode mode, const tcu::IVec2& dstSize, const tcu::IVec3& srcSize, const tcu::Vec3& sq, const tcu::Vec3& tq, const tcu::Vec3& rq) 278c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 279c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dux = (sq.z() - sq.x()) * (float)srcSize.x(); 280c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float duy = (sq.y() - sq.x()) * (float)srcSize.x(); 281c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvx = (tq.z() - tq.x()) * (float)srcSize.y(); 282c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvy = (tq.y() - tq.x()) * (float)srcSize.y(); 283c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dwx = (rq.z() - rq.x()) * (float)srcSize.z(); 284c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dwy = (rq.y() - rq.x()) * (float)srcSize.z(); 285c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dx = (float)dstSize.x(); 286c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dy = (float)dstSize.y(); 287c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 288c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return computeLodFromDerivates(mode, dux/dx, dvx/dx, dwx/dx, duy/dy, dvy/dy, dwy/dy); 289c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 290c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 291c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline float projectedTriInterpolate (const tcu::Vec3& s, const tcu::Vec3& w, float nx, float ny) 292c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 293c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]); 294c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 295c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 296c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline float triDerivateX (const tcu::Vec3& s, const tcu::Vec3& w, float wx, float width, float ny) 297c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 298c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float d = w[1]*w[2]*(width*(ny - 1.0f) + wx) - w[0]*(w[2]*width*ny + w[1]*wx); 299c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return (w[0]*w[1]*w[2]*width * (w[1]*(s[0] - s[2])*(ny - 1.0f) + ny*(w[2]*(s[1] - s[0]) + w[0]*(s[2] - s[1])))) / (d*d); 300c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 301c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 302c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline float triDerivateY (const tcu::Vec3& s, const tcu::Vec3& w, float wy, float height, float nx) 303c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 304c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float d = w[1]*w[2]*(height*(nx - 1.0f) + wy) - w[0]*(w[1]*height*nx + w[2]*wy); 305c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return (w[0]*w[1]*w[2]*height * (w[2]*(s[0] - s[1])*(nx - 1.0f) + nx*(w[0]*(s[1] - s[2]) + w[1]*(s[2] - s[0])))) / (d*d); 306c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 307c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 308c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// 1D lookup LOD. 309c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic float computeProjectedTriLod (LodMode mode, const tcu::Vec3& u, const tcu::Vec3& projection, float wx, float wy, float width, float height) 310c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 311c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Exact derivatives. 312c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dudx = triDerivateX(u, projection, wx, width, wy/height); 313c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dudy = triDerivateY(u, projection, wy, height, wx/width); 314c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 315c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return computeLodFromDerivates(mode, dudx, dudy); 316c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 317c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 318c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// 2D lookup LOD. 319c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic float computeProjectedTriLod (LodMode mode, const tcu::Vec3& u, const tcu::Vec3& v, const tcu::Vec3& projection, float wx, float wy, float width, float height) 320c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 321c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Exact derivatives. 322c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dudx = triDerivateX(u, projection, wx, width, wy/height); 323c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvdx = triDerivateX(v, projection, wx, width, wy/height); 324c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dudy = triDerivateY(u, projection, wy, height, wx/width); 325c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvdy = triDerivateY(v, projection, wy, height, wx/width); 326c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 327c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return computeLodFromDerivates(mode, dudx, dvdx, dudy, dvdy); 328c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 329c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 330c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// 3D lookup LOD. 331c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic float computeProjectedTriLod (LodMode mode, const tcu::Vec3& u, const tcu::Vec3& v, const tcu::Vec3& w, const tcu::Vec3& projection, float wx, float wy, float width, float height) 332c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 333c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Exact derivatives. 334c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dudx = triDerivateX(u, projection, wx, width, wy/height); 335c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvdx = triDerivateX(v, projection, wx, width, wy/height); 336c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dwdx = triDerivateX(w, projection, wx, width, wy/height); 337c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dudy = triDerivateY(u, projection, wy, height, wx/width); 338c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dvdy = triDerivateY(v, projection, wy, height, wx/width); 339c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dwdy = triDerivateY(w, projection, wy, height, wx/width); 340c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 341c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return computeLodFromDerivates(mode, dudx, dvdx, dwdx, dudy, dvdy, dwdy); 342c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 343c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 344c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline tcu::Vec4 execSample (const tcu::Texture1DView& src, const ReferenceParams& params, float s, float lod) 345c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 346c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.samplerType == SAMPLERTYPE_SHADOW) 347c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, lod), 0.0, 0.0, 1.0f); 348c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 349c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return src.sample(params.sampler, s, lod); 350c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 351c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 352c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline tcu::Vec4 execSample (const tcu::Texture2DView& src, const ReferenceParams& params, float s, float t, float lod) 353c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 354c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.samplerType == SAMPLERTYPE_SHADOW) 355c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, lod), 0.0, 0.0, 1.0f); 356c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 357c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return src.sample(params.sampler, s, t, lod); 358c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 359c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 360c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline tcu::Vec4 execSample (const tcu::TextureCubeView& src, const ReferenceParams& params, float s, float t, float r, float lod) 361c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 362c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.samplerType == SAMPLERTYPE_SHADOW) 363c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, lod), 0.0, 0.0, 1.0f); 364c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 365c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return src.sample(params.sampler, s, t, r, lod); 366c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 367c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 368c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline tcu::Vec4 execSample (const tcu::Texture2DArrayView& src, const ReferenceParams& params, float s, float t, float r, float lod) 369c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 370c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.samplerType == SAMPLERTYPE_SHADOW) 371c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, lod), 0.0, 0.0, 1.0f); 372c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 373c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return src.sample(params.sampler, s, t, r, lod); 374c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 375c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 376c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline tcu::Vec4 execSample (const tcu::TextureCubeArrayView& src, const ReferenceParams& params, float s, float t, float r, float q, float lod) 377c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 378c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.samplerType == SAMPLERTYPE_SHADOW) 379c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, q, lod), 0.0, 0.0, 1.0f); 380c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 381c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return src.sample(params.sampler, s, t, r, q, lod); 382c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 383c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 384c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic inline tcu::Vec4 execSample (const tcu::Texture1DArrayView& src, const ReferenceParams& params, float s, float t, float lod) 385c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 386c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.samplerType == SAMPLERTYPE_SHADOW) 387c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, lod), 0.0, 0.0, 1.0f); 388c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 389c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return src.sample(params.sampler, s, t, lod); 390c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 391c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 392c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture1DView& rawSrc, const tcu::Vec4& sq, const ReferenceParams& params) 393c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 394c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 395c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 396c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 397c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 398c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 399c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 400c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight()); 401c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int srcSize = src.getWidth(); 402c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 403c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 404c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 405c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triLod[2] = { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0]) + lodBias, params.minLod, params.maxLod), 406c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1]) + lodBias, params.minLod, params.maxLod) }; 407c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 408c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 409c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 410c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 411c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 412c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float yf = ((float)y + 0.5f) / (float)dst.getHeight(); 413c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float xf = ((float)x + 0.5f) / (float)dst.getWidth(); 414c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 415c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule. 416c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triX = triNdx ? 1.0f-xf : xf; 417c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triY = triNdx ? 1.0f-yf : yf; 418c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 419c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY); 420c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = triLod[triNdx]; 421c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 422c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, s, lod) * params.colorScale + params.colorBias, x, y); 423c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 424c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 425c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 426c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 427c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture2DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const ReferenceParams& params) 428c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 429c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 430c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 431c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 432c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 433c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 434c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 435c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight()); 436c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()); 437c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 438c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 439c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 440c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 441c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triLod[2] = { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias, params.minLod, params.maxLod), 442c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias, params.minLod, params.maxLod) }; 443c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 444c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 445c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 446c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 447c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 448c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float yf = ((float)y + 0.5f) / (float)dst.getHeight(); 449c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float xf = ((float)x + 0.5f) / (float)dst.getWidth(); 450c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 451c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule. 452c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triX = triNdx ? 1.0f-xf : xf; 453c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triY = triNdx ? 1.0f-yf : yf; 454c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 455c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY); 456c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float t = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY); 457c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = triLod[triNdx]; 458c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 459c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, x, y); 460c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 461c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 462c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 463c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 464c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureProjected (const tcu::SurfaceAccess& dst, const tcu::Texture1DView& rawSrc, const tcu::Vec4& sq, const ReferenceParams& params) 465c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 466c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 467c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 468c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 469c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 470c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 471c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dstW = (float)dst.getWidth(); 472c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dstH = (float)dst.getHeight(); 473c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 474c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 uq = sq * (float)src.getWidth(); 475c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 476c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 477c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triU[2] = { uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1) }; 478c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triW[2] = { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) }; 479c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 480c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < dst.getHeight(); py++) 481c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 482c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < dst.getWidth(); px++) 483c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 484c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float wx = (float)px + 0.5f; 485c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float wy = (float)py + 0.5f; 486c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float nx = wx / dstW; 487c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float ny = wy / dstH; 488c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 489c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = nx + ny >= 1.0f ? 1 : 0; 490c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triWx = triNdx ? dstW - wx : wx; 491c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triWy = triNdx ? dstH - wy : wy; 492c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triNx = triNdx ? 1.0f - nx : nx; 493c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triNy = triNdx ? 1.0f - ny : ny; 494c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 495c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy); 496c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = computeProjectedTriLod(params.lodMode, triU[triNdx], triW[triNdx], triWx, triWy, (float)dst.getWidth(), (float)dst.getHeight()) 497c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket + lodBias; 498c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 499c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, s, lod) * params.colorScale + params.colorBias, px, py); 500c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 501c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 502c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 503c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 504c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureProjected (const tcu::SurfaceAccess& dst, const tcu::Texture2DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const ReferenceParams& params) 505c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 506c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 507c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 508c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 509c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 510c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 511c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dstW = (float)dst.getWidth(); 512c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dstH = (float)dst.getHeight(); 513c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 514c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 uq = sq * (float)src.getWidth(); 515c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 vq = tq * (float)src.getHeight(); 516c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 517c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 518c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 519c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triU[2] = { uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1) }; 520c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triV[2] = { vq.swizzle(0, 1, 2), vq.swizzle(3, 2, 1) }; 521c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triW[2] = { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) }; 522c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 523c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < dst.getHeight(); py++) 524c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 525c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < dst.getWidth(); px++) 526c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 527c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float wx = (float)px + 0.5f; 528c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float wy = (float)py + 0.5f; 529c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float nx = wx / dstW; 530c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float ny = wy / dstH; 531c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 532c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = nx + ny >= 1.0f ? 1 : 0; 533c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triWx = triNdx ? dstW - wx : wx; 534c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triWy = triNdx ? dstH - wy : wy; 535c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triNx = triNdx ? 1.0f - nx : nx; 536c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triNy = triNdx ? 1.0f - ny : ny; 537c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 538c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy); 539c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float t = projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy); 540c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = computeProjectedTriLod(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triWx, triWy, (float)dst.getWidth(), (float)dst.getHeight()) 541c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket + lodBias; 542c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 543c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, px, py); 544c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 545c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 546c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 547c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 548c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture2DView& src, const float* texCoord, const ReferenceParams& params) 549c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 550c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView view = getSubView(src, params.baseLevel, params.maxLevel); 551c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]); 552c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]); 553c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 554c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.flags & ReferenceParams::PROJECTED) 555c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureProjected(dst, view, sq, tq, params); 556c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 557c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureNonProjected(dst, view, sq, tq, params); 558c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 559c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 560c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture1DView& src, const float* texCoord, const ReferenceParams& params) 561c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 562c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DView view = getSubView(src, params.baseLevel, params.maxLevel); 563c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]); 564c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 565c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.flags & ReferenceParams::PROJECTED) 566c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureProjected(dst, view, sq, params); 567c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 568c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureNonProjected(dst, view, sq, params); 569c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 570c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 571c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic float computeCubeLodFromDerivates (LodMode lodMode, const tcu::Vec3& coord, const tcu::Vec3& coordDx, const tcu::Vec3& coordDy, const int faceSize) 572c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 573c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::CubeFace face = tcu::selectCubeFace(coord); 574c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int maNdx = 0; 575c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int sNdx = 0; 576c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int tNdx = 0; 577c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 578c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // \note Derivate signs don't matter when computing lod 579c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (face) 580c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 581c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_X: 582c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_X: maNdx = 0; sNdx = 2; tNdx = 1; break; 583c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Y: 584c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Y: maNdx = 1; sNdx = 0; tNdx = 2; break; 585c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Z: 586c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Z: maNdx = 2; sNdx = 0; tNdx = 1; break; 587c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 588c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(DE_FALSE); 589c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 590c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 591c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 592c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float sc = coord[sNdx]; 593c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float tc = coord[tNdx]; 594c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ma = de::abs(coord[maNdx]); 595c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float scdx = coordDx[sNdx]; 596c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float tcdx = coordDx[tNdx]; 597c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float madx = de::abs(coordDx[maNdx]); 598c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float scdy = coordDy[sNdx]; 599c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float tcdy = coordDy[tNdx]; 600c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float mady = de::abs(coordDy[maNdx]); 601c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dudx = float(faceSize) * 0.5f * (scdx*ma - sc*madx) / (ma*ma); 602c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dvdx = float(faceSize) * 0.5f * (tcdx*ma - tc*madx) / (ma*ma); 603c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dudy = float(faceSize) * 0.5f * (scdy*ma - sc*mady) / (ma*ma); 604c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dvdy = float(faceSize) * 0.5f * (tcdy*ma - tc*mady) / (ma*ma); 605c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 606c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return computeLodFromDerivates(lodMode, dudx, dvdx, dudy, dvdy); 607c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 608c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 609c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 610c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureCube (const tcu::SurfaceAccess& dst, const tcu::TextureCubeView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params) 611c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 612c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 613c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 614c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 615c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 616c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight()); 617c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 618c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 619c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getSize(); 620c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 621c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 622c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 623c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 624c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 625c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) }; 626c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 627c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float lodBias ((params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f); 628c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 629c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < dst.getHeight(); py++) 630c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 631c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < dst.getWidth(); px++) 632c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 633c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 634c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 635c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 636c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 637c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 638c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 639c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 640c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 641c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 642c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (triangleInterpolate(triS[triNdx], triNx, triNy), 643c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triangleInterpolate(triT[triNdx], triNx, triNy), 644c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triangleInterpolate(triR[triNdx], triNx, triNy)); 645c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 646c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 647c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 648c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 649c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 650c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 651c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 652c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float lod = de::clamp(computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, srcSize) + lodBias, params.minLod, params.maxLod); 653c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 654c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, coord.x(), coord.y(), coord.z(), lod) * params.colorScale + params.colorBias, px, py); 655c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 656c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 657c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 658c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 659c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid sampleTexture (const tcu::SurfaceAccess& dst, const tcu::TextureCubeView& src, const float* texCoord, const ReferenceParams& params) 660c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 661c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView view = getSubView(src, params.baseLevel, params.maxLevel); 662c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 663c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 664c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 665c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 666c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return sampleTextureCube(dst, view, sq, tq, rq, params); 667c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 668c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 669c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture2DArrayView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params) 670c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 671c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 672c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 673c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 674c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 675c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 676c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 677c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight()); 678c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()); 679c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 680c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 681c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 682c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 683c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 684c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triLod[2] = { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias, params.minLod, params.maxLod), 685c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias, params.minLod, params.maxLod) }; 686c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 687c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 688c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 689c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 690c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 691c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float yf = ((float)y + 0.5f) / (float)dst.getHeight(); 692c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float xf = ((float)x + 0.5f) / (float)dst.getWidth(); 693c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 694c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule. 695c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triX = triNdx ? 1.0f-xf : xf; 696c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triY = triNdx ? 1.0f-yf : yf; 697c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 698c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY); 699c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float t = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY); 700c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float r = triangleInterpolate(triR[triNdx].x(), triR[triNdx].y(), triR[triNdx].z(), triX, triY); 701c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = triLod[triNdx]; 702c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 703c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, s, t, r, lod) * params.colorScale + params.colorBias, x, y); 704c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 705c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 706c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 707c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 708c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture2DArrayView& src, const float* texCoord, const ReferenceParams& params) 709c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 710c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 711c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 712c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 713c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 714c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(!(params.flags & ReferenceParams::PROJECTED)); // \todo [2012-02-17 pyry] Support projected lookups. 715c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureNonProjected(dst, src, sq, tq, rq, params); 716c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 717c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 718c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture1DArrayView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const ReferenceParams& params) 719c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 720c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 721c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 722c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DArrayView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 723c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 724c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 725c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 726c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight()); 727c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket deInt32 srcSize = src.getWidth(); 728c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 729c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 730c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 731c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 732c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triLod[2] = { computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0]) + lodBias, 733c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1]) + lodBias}; 734c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 735c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 736c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 737c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 738c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 739c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float yf = ((float)y + 0.5f) / (float)dst.getHeight(); 740c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float xf = ((float)x + 0.5f) / (float)dst.getWidth(); 741c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 742c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule. 743c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triX = triNdx ? 1.0f-xf : xf; 744c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triY = triNdx ? 1.0f-yf : yf; 745c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 746c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY); 747c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float t = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY); 748c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = triLod[triNdx]; 749c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 750c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, x, y); 751c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 752c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 753c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 754c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 755c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture1DArrayView& src, const float* texCoord, const ReferenceParams& params) 756c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 757c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]); 758c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]); 759c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 760c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(!(params.flags & ReferenceParams::PROJECTED)); // \todo [2014-06-09 mika] Support projected lookups. 761c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureNonProjected(dst, src, sq, tq, params); 762c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 763c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 764c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureNonProjected (const tcu::SurfaceAccess& dst, const tcu::Texture3DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params) 765c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 766c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 767c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 768c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 769c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 770c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 771c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 772c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight()); 773c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::IVec3 srcSize = tcu::IVec3(src.getWidth(), src.getHeight(), src.getDepth()); 774c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 775c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 776c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 777c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 778c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 779c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triLod[2] = { de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0], triR[0]) + lodBias, params.minLod, params.maxLod), 780c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1], triR[1]) + lodBias, params.minLod, params.maxLod) }; 781c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 782c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 783c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 784c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 785c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 786c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float yf = ((float)y + 0.5f) / (float)dst.getHeight(); 787c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float xf = ((float)x + 0.5f) / (float)dst.getWidth(); 788c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 789c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule. 790c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triX = triNdx ? 1.0f-xf : xf; 791c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triY = triNdx ? 1.0f-yf : yf; 792c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 793c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY); 794c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float t = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY); 795c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float r = triangleInterpolate(triR[triNdx].x(), triR[triNdx].y(), triR[triNdx].z(), triX, triY); 796c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = triLod[triNdx]; 797c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 798c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(src.sample(params.sampler, s, t, r, lod) * params.colorScale + params.colorBias, x, y); 799c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 800c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 801c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 802c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 803c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureProjected (const tcu::SurfaceAccess& dst, const tcu::Texture3DView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const ReferenceParams& params) 804c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 805c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 806c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 807c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 808c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 809c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 810c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dstW = (float)dst.getWidth(); 811c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float dstH = (float)dst.getHeight(); 812c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 813c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 uq = sq * (float)src.getWidth(); 814c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 vq = tq * (float)src.getHeight(); 815c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 wq = rq * (float)src.getDepth(); 816c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 817c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 818c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 819c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 820c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triU[2] = { uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1) }; 821c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triV[2] = { vq.swizzle(0, 1, 2), vq.swizzle(3, 2, 1) }; 822c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triW[2] = { wq.swizzle(0, 1, 2), wq.swizzle(3, 2, 1) }; 823c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triP[2] = { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) }; 824c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 825c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < dst.getHeight(); py++) 826c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 827c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < dst.getWidth(); px++) 828c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 829c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float wx = (float)px + 0.5f; 830c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float wy = (float)py + 0.5f; 831c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float nx = wx / dstW; 832c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float ny = wy / dstH; 833c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 834c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int triNdx = nx + ny >= 1.0f ? 1 : 0; 835c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triWx = triNdx ? dstW - wx : wx; 836c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triWy = triNdx ? dstH - wy : wy; 837c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triNx = triNdx ? 1.0f - nx : nx; 838c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float triNy = triNdx ? 1.0f - ny : ny; 839c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 840c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float s = projectedTriInterpolate(triS[triNdx], triP[triNdx], triNx, triNy); 841c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float t = projectedTriInterpolate(triT[triNdx], triP[triNdx], triNx, triNy); 842c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float r = projectedTriInterpolate(triR[triNdx], triP[triNdx], triNx, triNy); 843c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float lod = computeProjectedTriLod(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triP[triNdx], triWx, triWy, (float)dst.getWidth(), (float)dst.getHeight()) 844c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket + lodBias; 845c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 846c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(src.sample(params.sampler, s, t, r, lod) * params.colorScale + params.colorBias, px, py); 847c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 848c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 849c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 850c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 851c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid sampleTexture (const tcu::SurfaceAccess& dst, const tcu::Texture3DView& src, const float* texCoord, const ReferenceParams& params) 852c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 853c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView view = getSubView(src, params.baseLevel, params.maxLevel); 854c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 855c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 856c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 857c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 858c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (params.flags & ReferenceParams::PROJECTED) 859c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureProjected(dst, view, sq, tq, rq, params); 860c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 861c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureNonProjected(dst, view, sq, tq, rq, params); 862c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 863c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 864c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic void sampleTextureCubeArray (const tcu::SurfaceAccess& dst, const tcu::TextureCubeArrayView& rawSrc, const tcu::Vec4& sq, const tcu::Vec4& tq, const tcu::Vec4& rq, const tcu::Vec4& qq, const ReferenceParams& params) 865c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 866c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Separate combined DS formats 867c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 868c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeArrayView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler); 869c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 870c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = (float)dst.getWidth(); 871c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = (float)dst.getHeight(); 872c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 873c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 874c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 875c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 876c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 877c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 triQ[2] = { qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1) }; 878c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1) }; 879c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 880c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f; 881c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 882c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < dst.getHeight(); py++) 883c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 884c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < dst.getWidth(); px++) 885c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 886c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 887c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 888c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 889c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 890c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 891c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 892c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 893c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 894c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 895c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (triangleInterpolate(triS[triNdx], triNx, triNy), 896c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triangleInterpolate(triT[triNdx], triNx, triNy), 897c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triangleInterpolate(triR[triNdx], triNx, triNy)); 898c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 899c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordQ = triangleInterpolate(triQ[triNdx], triNx, triNy); 900c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 901c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 902c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 903c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 904c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 905c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 906c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 907c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 908c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float lod = de::clamp(computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, src.getSize()) + lodBias, params.minLod, params.maxLod); 909c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 910c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(execSample(src, params, coord.x(), coord.y(), coord.z(), coordQ, lod) * params.colorScale + params.colorBias, px, py); 911c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 912c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 913c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 914c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 915c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid sampleTexture (const tcu::SurfaceAccess& dst, const tcu::TextureCubeArrayView& src, const float* texCoord, const ReferenceParams& params) 916c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 917c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[4+0], texCoord[8+0], texCoord[12+0]); 918c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[4+1], texCoord[8+1], texCoord[12+1]); 919c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[4+2], texCoord[8+2], texCoord[12+2]); 920c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 qq = tcu::Vec4(texCoord[0+3], texCoord[4+3], texCoord[8+3], texCoord[12+3]); 921c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 922c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTextureCubeArray(dst, src, sq, tq, rq, qq, params); 923c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 924c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 925c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid fetchTexture (const tcu::SurfaceAccess& dst, const tcu::ConstPixelBufferAccess& src, const float* texCoord, const tcu::Vec4& colorScale, const tcu::Vec4& colorBias) 926c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 927c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]); 928c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 929c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 930c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 931c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 932c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 933c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 934c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float yf = ((float)y + 0.5f) / (float)dst.getHeight(); 935c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float xf = ((float)x + 0.5f) / (float)dst.getWidth(); 936c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 937c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule. 938c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triX = triNdx ? 1.0f-xf : xf; 939c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triY = triNdx ? 1.0f-yf : yf; 940c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 941c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float s = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY); 942c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 943c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.setPixel(src.getPixel((int)s, 0) * colorScale + colorBias, x, y); 944c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 945c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 946c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 947c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 948c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool compareImages (tcu::TestLog& log, const tcu::Surface& reference, const tcu::Surface& rendered, tcu::RGBA threshold) 949c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 950c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::pixelThresholdCompare(log, "Result", "Image comparison result", reference, rendered, threshold, tcu::COMPARE_LOG_RESULT); 951c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 952c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 953c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool compareImages (tcu::TestLog& log, const char* name, const char* desc, const tcu::Surface& reference, const tcu::Surface& rendered, tcu::RGBA threshold) 954c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 955c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::pixelThresholdCompare(log, name, desc, reference, rendered, threshold, tcu::COMPARE_LOG_RESULT); 956c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 957c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 958c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint measureAccuracy (tcu::TestLog& log, const tcu::Surface& reference, const tcu::Surface& rendered, int bestScoreDiff, int worstScoreDiff) 959c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 960c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::measurePixelDiffAccuracy(log, "Result", "Image comparison result", reference, rendered, bestScoreDiff, worstScoreDiff, tcu::COMPARE_LOG_EVERYTHING); 961c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 962c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 963c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline int rangeDiff (int x, int a, int b) 964c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 965c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (x < a) 966c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return a-x; 967c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else if (x > b) 968c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return x-b; 969c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 970c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return 0; 971c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 972c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 973c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline tcu::RGBA rangeDiff (tcu::RGBA p, tcu::RGBA a, tcu::RGBA b) 974c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 975c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int rMin = de::min(a.getRed(), b.getRed()); 976c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int rMax = de::max(a.getRed(), b.getRed()); 977c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int gMin = de::min(a.getGreen(), b.getGreen()); 978c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int gMax = de::max(a.getGreen(), b.getGreen()); 979c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int bMin = de::min(a.getBlue(), b.getBlue()); 980c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int bMax = de::max(a.getBlue(), b.getBlue()); 981c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int aMin = de::min(a.getAlpha(), b.getAlpha()); 982c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int aMax = de::max(a.getAlpha(), b.getAlpha()); 983c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 984c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return tcu::RGBA(rangeDiff(p.getRed(), rMin, rMax), 985c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket rangeDiff(p.getGreen(), gMin, gMax), 986c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket rangeDiff(p.getBlue(), bMin, bMax), 987c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket rangeDiff(p.getAlpha(), aMin, aMax)); 988c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 989c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 990c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketinline bool rangeCompare (tcu::RGBA p, tcu::RGBA a, tcu::RGBA b, tcu::RGBA threshold) 991c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 992c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::RGBA diff = rangeDiff(p, a, b); 993c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return diff.getRed() <= threshold.getRed() && 994c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket diff.getGreen() <= threshold.getGreen() && 995c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket diff.getBlue() <= threshold.getBlue() && 996c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket diff.getAlpha() <= threshold.getAlpha(); 997c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 998c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 999c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoord1D (std::vector<float>& dst, float left, float right) 1000c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1001c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(4); 1002c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1003c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0] = left; 1004c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[1] = left; 1005c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[2] = right; 1006c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[3] = right; 1007c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1008c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1009c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoord1DArray (std::vector<float>& dst, int layerNdx, float left, float right) 1010c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1011c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(4*2); 1012c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1013c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0] = left; dst[1] = (float)layerNdx; 1014c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[2] = left; dst[3] = (float)layerNdx; 1015c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[4] = right; dst[5] = (float)layerNdx; 1016c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[6] = right; dst[7] = (float)layerNdx; 1017c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1018c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1019c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoord2D (std::vector<float>& dst, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight) 1020c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1021c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(4*2); 1022c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1023c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0] = bottomLeft.x(); dst[1] = bottomLeft.y(); 1024c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[2] = bottomLeft.x(); dst[3] = topRight.y(); 1025c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[4] = topRight.x(); dst[5] = bottomLeft.y(); 1026c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[6] = topRight.x(); dst[7] = topRight.y(); 1027c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1028c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1029c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoord2DArray (std::vector<float>& dst, int layerNdx, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight) 1030c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1031c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(4*3); 1032c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1033c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0] = bottomLeft.x(); dst[ 1] = bottomLeft.y(); dst[ 2] = (float)layerNdx; 1034c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[3] = bottomLeft.x(); dst[ 4] = topRight.y(); dst[ 5] = (float)layerNdx; 1035c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[6] = topRight.x(); dst[ 7] = bottomLeft.y(); dst[ 8] = (float)layerNdx; 1036c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[9] = topRight.x(); dst[10] = topRight.y(); dst[11] = (float)layerNdx; 1037c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1038c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1039c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoord3D (std::vector<float>& dst, const tcu::Vec3& p0, const tcu::Vec3& p1, const tcu::IVec3& dirSwz) 1040c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1041c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 f0 = tcu::Vec3(0.0f, 0.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]); 1042c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 f1 = tcu::Vec3(0.0f, 1.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]); 1043c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 f2 = tcu::Vec3(1.0f, 0.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]); 1044c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 f3 = tcu::Vec3(1.0f, 1.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]); 1045c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1046c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 v0 = p0 + (p1-p0)*f0; 1047c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 v1 = p0 + (p1-p0)*f1; 1048c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 v2 = p0 + (p1-p0)*f2; 1049c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec3 v3 = p0 + (p1-p0)*f3; 1050c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1051c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(4*3); 1052c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1053c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0] = v0.x(); dst[ 1] = v0.y(); dst[ 2] = v0.z(); 1054c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[3] = v1.x(); dst[ 4] = v1.y(); dst[ 5] = v1.z(); 1055c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[6] = v2.x(); dst[ 7] = v2.y(); dst[ 8] = v2.z(); 1056c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[9] = v3.x(); dst[10] = v3.y(); dst[11] = v3.z(); 1057c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1058c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1059c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoordCube (std::vector<float>& dst, tcu::CubeFace face) 1060c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1061c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const float texCoordNegX[] = 1062c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1063c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, 1.0f, -1.0f, 1064c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, -1.0f, -1.0f, 1065c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, 1.0f, 1.0f, 1066c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, -1.0f, 1.0f 1067c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1068c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const float texCoordPosX[] = 1069c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1070c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket +1.0f, 1.0f, 1.0f, 1071c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket +1.0f, -1.0f, 1.0f, 1072c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket +1.0f, 1.0f, -1.0f, 1073c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket +1.0f, -1.0f, -1.0f 1074c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1075c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const float texCoordNegY[] = 1076c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1077c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, -1.0f, 1.0f, 1078c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, -1.0f, -1.0f, 1079c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, -1.0f, 1.0f, 1080c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, -1.0f, -1.0f 1081c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1082c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const float texCoordPosY[] = 1083c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1084c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, +1.0f, -1.0f, 1085c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, +1.0f, 1.0f, 1086c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, +1.0f, -1.0f, 1087c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, +1.0f, 1.0f 1088c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1089c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const float texCoordNegZ[] = 1090c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1091c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, 1.0f, -1.0f, 1092c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, -1.0f, -1.0f, 1093c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, 1.0f, -1.0f, 1094c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, -1.0f, -1.0f 1095c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1096c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const float texCoordPosZ[] = 1097c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1098c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, 1.0f, +1.0f, 1099c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket -1.0f, -1.0f, +1.0f, 1100c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, 1.0f, +1.0f, 1101c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1.0f, -1.0f, +1.0f 1102c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1103c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1104c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord = DE_NULL; 1105c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int texCoordSize = DE_LENGTH_OF_ARRAY(texCoordNegX); 1106c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1107c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (face) 1108c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1109c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_X: texCoord = texCoordNegX; break; 1110c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_X: texCoord = texCoordPosX; break; 1111c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Y: texCoord = texCoordNegY; break; 1112c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Y: texCoord = texCoordPosY; break; 1113c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Z: texCoord = texCoordNegZ; break; 1114c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Z: texCoord = texCoordPosZ; break; 1115c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 1116c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(DE_FALSE); 1117c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return; 1118c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1119c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1120c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(texCoordSize); 1121c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::copy(texCoord, texCoord+texCoordSize, dst.begin()); 1122c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1123c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1124c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoordCube (std::vector<float>& dst, tcu::CubeFace face, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight) 1125c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1126c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int sRow = 0; 1127c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int tRow = 0; 1128c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int mRow = 0; 1129c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float sSign = 1.0f; 1130c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float tSign = 1.0f; 1131c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float mSign = 1.0f; 1132c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1133c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (face) 1134c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1135c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_X: mRow = 0; sRow = 2; tRow = 1; mSign = -1.0f; tSign = -1.0f; break; 1136c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_X: mRow = 0; sRow = 2; tRow = 1; sSign = -1.0f; tSign = -1.0f; break; 1137c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Y: mRow = 1; sRow = 0; tRow = 2; mSign = -1.0f; tSign = -1.0f; break; 1138c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Y: mRow = 1; sRow = 0; tRow = 2; break; 1139c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Z: mRow = 2; sRow = 0; tRow = 1; mSign = -1.0f; sSign = -1.0f; tSign = -1.0f; break; 1140c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Z: mRow = 2; sRow = 0; tRow = 1; tSign = -1.0f; break; 1141c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 1142c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(DE_FALSE); 1143c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return; 1144c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1145c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1146c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(3*4); 1147c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1148c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0+mRow] = mSign; 1149c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[3+mRow] = mSign; 1150c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[6+mRow] = mSign; 1151c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[9+mRow] = mSign; 1152c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1153c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0+sRow] = sSign * bottomLeft.x(); 1154c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[3+sRow] = sSign * bottomLeft.x(); 1155c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[6+sRow] = sSign * topRight.x(); 1156c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[9+sRow] = sSign * topRight.x(); 1157c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1158c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[0+tRow] = tSign * bottomLeft.y(); 1159c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[3+tRow] = tSign * topRight.y(); 1160c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[6+tRow] = tSign * bottomLeft.y(); 1161c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[9+tRow] = tSign * topRight.y(); 1162c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1163c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1164c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketvoid computeQuadTexCoordCubeArray (std::vector<float>& dst, tcu::CubeFace face, const tcu::Vec2& bottomLeft, const tcu::Vec2& topRight, const tcu::Vec2& layerRange) 1165c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1166c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int sRow = 0; 1167c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int tRow = 0; 1168c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int mRow = 0; 1169c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int qRow = 3; 1170c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float sSign = 1.0f; 1171c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float tSign = 1.0f; 1172c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket float mSign = 1.0f; 1173c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float l0 = layerRange.x(); 1174c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float l1 = layerRange.y(); 1175c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1176c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket switch (face) 1177c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1178c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_X: mRow = 0; sRow = 2; tRow = 1; mSign = -1.0f; tSign = -1.0f; break; 1179c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_X: mRow = 0; sRow = 2; tRow = 1; sSign = -1.0f; tSign = -1.0f; break; 1180c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Y: mRow = 1; sRow = 0; tRow = 2; mSign = -1.0f; tSign = -1.0f; break; 1181c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Y: mRow = 1; sRow = 0; tRow = 2; break; 1182c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_NEGATIVE_Z: mRow = 2; sRow = 0; tRow = 1; mSign = -1.0f; sSign = -1.0f; tSign = -1.0f; break; 1183c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket case tcu::CUBEFACE_POSITIVE_Z: mRow = 2; sRow = 0; tRow = 1; tSign = -1.0f; break; 1184c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket default: 1185c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(DE_FALSE); 1186c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return; 1187c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1188c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1189c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst.resize(4*4); 1190c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1191c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 0+mRow] = mSign; 1192c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 4+mRow] = mSign; 1193c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 8+mRow] = mSign; 1194c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[12+mRow] = mSign; 1195c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1196c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 0+sRow] = sSign * bottomLeft.x(); 1197c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 4+sRow] = sSign * bottomLeft.x(); 1198c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 8+sRow] = sSign * topRight.x(); 1199c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[12+sRow] = sSign * topRight.x(); 1200c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1201c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 0+tRow] = tSign * bottomLeft.y(); 1202c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 4+tRow] = tSign * topRight.y(); 1203c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 8+tRow] = tSign * bottomLeft.y(); 1204c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[12+tRow] = tSign * topRight.y(); 1205c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1206c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (l0 != l1) 1207c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1208c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 0+qRow] = l0; 1209c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 4+qRow] = l0*0.5f + l1*0.5f; 1210c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 8+qRow] = l0*0.5f + l1*0.5f; 1211c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[12+qRow] = l1; 1212c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1213c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 1214c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1215c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 0+qRow] = l0; 1216c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 4+qRow] = l0; 1217c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[ 8+qRow] = l0; 1218c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket dst[12+qRow] = l0; 1219c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1220c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1221c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1222c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// Texture result verification 1223c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1224c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1225c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1226c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1227c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1228c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DView& baseView, 1229c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1230c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1231c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1232c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1233c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1234c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1235c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1236c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1237c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1238c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1239c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 1240c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1241c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]); 1242c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1243c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1244c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1245c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1246c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getWidth(); 1247c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1248c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 1249c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1250c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1251c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1252c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1253c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1254c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1255c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1256c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1257c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1258c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1259c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1260c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1261c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1262c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1263c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1264c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1265c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1266c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1267c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1268c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1269c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1270c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1271c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1272c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1273c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1274c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1275c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1276c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1277c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1278c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1279c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1280c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1281c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1282c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1283c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1284c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1285c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 1286c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1287c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1288c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1289c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1290c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1291c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coord = projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy); 1292c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDx = triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * float(srcSize); 1293c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDy = triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx) * float(srcSize); 1294c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1295c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx, coordDy, lodPrec); 1296c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1297c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1298c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1299c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1300c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1301c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1302c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1303c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1304c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1305c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDxo = triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * float(srcSize); 1306c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDyo = triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * float(srcSize); 1307c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec); 1308c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1309c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1310c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1311c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1312c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1313c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1314c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 1315c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1316c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1317c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1318c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1319c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1320c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1321c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1322c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1323c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1324c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1325c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1326c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1327c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1328c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1329c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1330c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1331c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView& baseView, 1332c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1333c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1334c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1335c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1336c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1337c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1338c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1339c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1340c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1341c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1342c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 1343c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1344c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]); 1345c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]); 1346c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1347c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1348c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1349c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1350c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()); 1351c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1352c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 1353c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1354c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1355c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1356c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1357c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1358c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1359c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1360c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1361c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1362c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1363c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1364c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1365c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1366c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1367c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1368c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1369c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1370c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1371c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1372c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1373c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1374c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1375c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1376c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1377c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1378c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1379c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1380c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1381c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1382c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1383c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1384c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1385c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1386c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1387c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1388c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1389c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1390c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 1391c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1392c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1393c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1394c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1395c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1396c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1397c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)); 1398c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1399c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 1400c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1401c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 1402c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1403c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 1404c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1405c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1406c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1407c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1408c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1409c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1410c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1411c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1412c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1413c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 1414c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 1415c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 1416c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 1417c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 1418c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1419c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1420c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1421c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1422c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1423c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1424c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 1425c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1426c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1427c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1428c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1429c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1430c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1431c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1432c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1433c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1434c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1435c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1436c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1437c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1438c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1439c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1440c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DView& src, 1441c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1442c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1443c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1444c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1445c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1446c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1447c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1448c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1449c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1450c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1451c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1452c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1453c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1454c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1455c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1456c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1457c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1458c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1459c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1460c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1461c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1462c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1463c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1464c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1465c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1466c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1467c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1468c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1469c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1470c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1471c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1472c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1473c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1474c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1475c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1476c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView& src, 1477c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1478c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1479c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1480c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1481c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1482c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1483c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1484c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1485c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1486c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1487c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1488c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1489c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1490c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1491c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1492c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1493c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1494c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1495c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1496c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1497c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1498c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1499c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1500c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1501c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1502c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1503c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1504c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1505c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1506c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1507c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1508c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1509c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1510c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1511c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1512c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1513c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1514c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView& baseView, 1515c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1516c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1517c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1518c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1519c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1520c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1521c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1522c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1523c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1524c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1525c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 1526c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1527c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 1528c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 1529c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 1530c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1531c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1532c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1533c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1534c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getSize(); 1535c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1536c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 1537c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1538c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1539c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 1540c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1541c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1542c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1543c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1544c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float posEps = 1.0f / float(1<<MIN_SUBPIXEL_BITS); 1545c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1546c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1547c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1548c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1549c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1550c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1551c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1552c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1553c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1554c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1555c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // \note Not strictly allowed by spec, but implementations do this in practice. 1556c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, -1), 1557c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, +1), 1558c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, -1), 1559c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, +1), 1560c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1561c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1562c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1563c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1564c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1565c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1566c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1567c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1568c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1569c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1570c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1571c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1572c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1573c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1574c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1575c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1576c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1577c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1578c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1579c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1580c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1581c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1582c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1583c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri0 = (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f; 1584c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri1 = (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f; 1585c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1586c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk = false; 1587c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1588c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(tri0 || tri1); 1589c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1590c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Pixel can belong to either of the triangles if it lies close enough to the edge. 1591c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++) 1592c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1593c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1594c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1595c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1596c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1597c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1598c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1599c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 1600c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 1601c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1602c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 1603c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 1604c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1605c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 1606c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 1607c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1608c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec); 1609c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1610c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1611c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1612c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1613c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1614c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1615c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1616c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1617c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1618c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordO (projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 1619c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 1620c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)); 1621c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo (triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 1622c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 1623c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)); 1624c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo (triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 1625c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 1626c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)); 1627c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec); 1628c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1629c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1630c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1631c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1632c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1633c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1634c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1635c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix)) 1636c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1637c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = true; 1638c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 1639c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1640c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1641c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1642c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1643c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1644c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1645c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1646c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1647c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1648c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1649c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1650c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1651c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1652c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1653c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1654c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1655c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1656c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView& src, 1657c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1658c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1659c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1660c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1661c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1662c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1663c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1664c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1665c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1666c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1667c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1668c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1669c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1670c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1671c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1672c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1673c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1674c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1675c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1676c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1677c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1678c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1679c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1680c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1681c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1682c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1683c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1684c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1685c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1686c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1687c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1688c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1689c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1690c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1691c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1692c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1693c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1694c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView& baseView, 1695c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1696c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1697c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1698c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1699c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1700c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1701c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1702c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1703c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1704c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1705c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 1706c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1707c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 1708c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 1709c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 1710c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1711c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1712c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1713c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1714c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec3 srcSize = tcu::IVec3(src.getWidth(), src.getHeight(), src.getDepth()); 1715c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1716c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 1717c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1718c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1719c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 1720c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1721c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1722c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1723c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1724c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float posEps = 1.0f / float(1<<MIN_SUBPIXEL_BITS); 1725c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1726c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1727c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1728c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1729c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1730c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1731c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1732c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1733c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1734c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1735c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1736c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1737c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1738c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1739c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1740c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1741c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1742c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1743c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1744c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1745c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1746c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1747c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1748c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1749c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1750c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1751c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1752c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1753c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1754c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1755c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1756c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1757c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri0 = (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f; 1758c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri1 = (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f; 1759c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1760c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk = false; 1761c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1762c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(tri0 || tri1); 1763c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1764c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Pixel can belong to either of the triangles if it lies close enough to the edge. 1765c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++) 1766c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1767c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1768c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1769c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1770c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1771c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1772c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1773c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 1774c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 1775c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx = tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1776c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 1777c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 1778c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy = tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1779c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 1780c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 1781c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1782c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDx.z(), coordDy.x(), coordDy.y(), coordDy.z(), lodPrec); 1783c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1784c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1785c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1786c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1787c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1788c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1789c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1790c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1791c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1792c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo = tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 1793c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 1794c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 1795c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo = tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 1796c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 1797c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 1798c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDxo.z(), coordDyo.x(), coordDyo.y(), coordDyo.z(), lodPrec); 1799c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1800c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1801c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1802c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1803c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1804c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1805c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1806c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix)) 1807c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1808c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = true; 1809c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 1810c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1811c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1812c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1813c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1814c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1815c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1816c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1817c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1818c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1819c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1820c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1821c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1822c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1823c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1824c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1825c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1826c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1827c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView& src, 1828c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1829c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1830c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1831c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1832c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1833c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1834c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1835c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1836c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1837c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1838c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1839c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1840c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1841c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1842c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1843c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1844c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1845c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1846c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1847c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1848c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1849c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1850c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1851c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1852c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1853c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1854c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1855c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1856c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1857c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1858c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1859c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1860c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1861c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1862c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1863c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1864c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1865c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DArrayView& baseView, 1866c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1867c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1868c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1869c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1870c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1871c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1872c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1873c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1874c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1875c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1876c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DArrayView src = getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler); 1877c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1878c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]); 1879c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]); 1880c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1881c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1882c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1883c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1884c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcSize = float(src.getWidth()); // For lod computation, thus #layers is ignored. 1885c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1886c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 1887c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1888c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1889c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1890c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1891c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1892c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1893c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1894c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1895c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1896c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1897c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1898c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1899c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1900c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1901c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1902c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1903c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1904c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1905c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1906c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1907c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1908c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1909c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1910c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1911c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1912c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1913c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1914c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1915c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1916c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1917c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1918c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1919c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1920c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1921c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1922c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1923c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1924c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 1925c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1926c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1927c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1928c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1929c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1930c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1931c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)); 1932c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDx = triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize; 1933c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDy = triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx) * srcSize; 1934c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1935c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx, coordDy, lodPrec); 1936c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1937c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1938c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1939c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1940c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1941c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1942c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1943c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1944c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1945c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDxo = triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize; 1946c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDyo = triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize; 1947c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec); 1948c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1949c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1950c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1951c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1952c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1953c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1954c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 1955c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1956c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1957c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1958c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1959c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1960c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1961c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1962c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1963c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1964c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1965c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1966c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1967c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1968c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1969c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1970c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1971c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1972c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView& baseView, 1973c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1974c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1975c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1976c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1977c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1978c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1979c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1980c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1981c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1982c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1983c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView src = getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler); 1984c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1985c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 1986c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 1987c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 1988c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1989c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1990c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1991c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1992c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()).asFloat(); // For lod computation, thus #layers is ignored. 1993c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1994c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 1995c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1996c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1997c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 1998c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1999c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2000c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2001c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2002c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2003c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2004c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2005c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2006c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2007c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2008c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2009c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2010c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2011c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2012c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2013c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2014c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2015c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2016c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 2017c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 2018c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 2019c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2020c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2021c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2022c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2023c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2024c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2025c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 2026c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 2027c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2028c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2029c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2030c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2031c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2032c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2033c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2034c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2035c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2036c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2037c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2038c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2039c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2040c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2041c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 2042c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2043c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize; 2044c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2045c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize; 2046c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2047c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 2048c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2049c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2050c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2051c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2052c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2053c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2054c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2055c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2056c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2057c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2058c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize; 2059c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2060c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize; 2061c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 2062c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2063c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2064c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2065c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2066c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2067c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2068c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 2069c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2070c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2071c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2072c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2073c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2074c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2075c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2076c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2077c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2078c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2079c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2080c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2081c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2082c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 2083c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 2084c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DArrayView& src, 2085c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2086c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2087c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2088c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2089c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 2090c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2091c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 2092c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 2093c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 2094c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 2095c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2096c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 2097c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2098c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 2099c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 2100c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2101c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2102c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 2103c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2104c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 2105c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 2106c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2107c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2108c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2109c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 2110c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2111c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2112c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2113c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2114c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2115c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 2116c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2117c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2118c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 2119c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 2120c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView& src, 2121c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2122c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2123c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2124c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2125c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 2126c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2127c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 2128c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 2129c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 2130c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 2131c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2132c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 2133c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2134c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 2135c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 2136c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2137c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2138c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 2139c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2140c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 2141c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 2142c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2143c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2144c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2145c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 2146c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2147c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2148c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2149c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2150c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2151c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 2152c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2153c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2154c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 2155c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 2156c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2157c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2158c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeArrayView& baseView, 2159c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2160c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2161c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2162c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec4& coordBits, 2163c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2164c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 2165c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2166c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2167c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2168c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2169c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 2170c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeArrayView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 2171c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2172c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[4+0], texCoord[8+0], texCoord[12+0]); 2173c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[4+1], texCoord[8+1], texCoord[12+1]); 2174c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[4+2], texCoord[8+2], texCoord[12+2]); 2175c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 qq = tcu::Vec4(texCoord[0+3], texCoord[4+3], texCoord[8+3], texCoord[12+3]); 2176c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2177c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2178c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2179c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2180c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getSize(); 2181c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2182c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 2183c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2184c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2185c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 2186c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triQ[2] = { qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1) }; 2187c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2188c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2189c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2190c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2191c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float posEps = 1.0f / float((1<<4) + 1); // ES3 requires at least 4 subpixel bits. 2192c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2193c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2194c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2195c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2196c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2197c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2198c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2199c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2200c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2201c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2202c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // \note Not strictly allowed by spec, but implementations do this in practice. 2203c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, -1), 2204c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, +1), 2205c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, -1), 2206c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, +1), 2207c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2208c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2209c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2210c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2211c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2212c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2213c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 2214c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 2215c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 2216c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2217c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2218c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2219c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2220c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2221c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2222c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 2223c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 2224c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2225c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2226c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2227c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2228c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2229c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2230c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri0 = nx + ny - posEps <= 1.0f; 2231c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri1 = nx + ny + posEps >= 1.0f; 2232c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2233c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk = false; 2234c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2235c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(tri0 || tri1); 2236c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2237c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Pixel can belong to either of the triangles if it lies close enough to the edge. 2238c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++) 2239c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2240c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2241c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2242c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2243c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2244c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2245c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2246c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2247c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy), 2248c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triQ[triNdx], triW[triNdx], triNx, triNy)); 2249c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2250c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 2251c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 2252c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2253c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 2254c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 2255c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2256c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeCubeLodBoundsFromDerivates(coord.toWidth<3>(), coordDx, coordDy, srcSize, lodPrec); 2257c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2258c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2259c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2260c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2261c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2262c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2263c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2264c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2265c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2266c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordO (projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2267c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 2268c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)); 2269c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo (triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2270c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 2271c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)); 2272c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo (triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2273c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 2274c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)); 2275c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec); 2276c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2277c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2278c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2279c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2280c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2281c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2282c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2283c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coordBits, coord, clampedLod, resPix)) 2284c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2285c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = true; 2286c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 2287c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2288c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2289c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2290c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2291c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2292c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2293c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2294c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2295c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2296c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2297c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2298c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2299c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2300c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2301c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2302c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 2303c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 2304c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeArrayView& src, 2305c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2306c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2307c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2308c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec4& coordBits, 2309c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2310c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 2311c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2312c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 2313c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 2314c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 2315c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 2316c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2317c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 2318c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2319c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 2320c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, coordBits, lodPrec, testCtx.getWatchDog()); 2321c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2322c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2323c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 2324c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2325c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 2326c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 2327c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2328c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2329c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2330c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 2331c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2332c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2333c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2334c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2335c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2336c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 2337c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2338c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2339c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// Shadow lookup verification 2340c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2341c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureCompareDiff (const tcu::ConstPixelBufferAccess& result, 2342c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2343c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2344c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView& src, 2345c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2346c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2347c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TexComparePrecision& comparePrec, 2348c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2349c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3& nonShadowThreshold) 2350c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2351c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2352c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2353c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2354c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]); 2355c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]); 2356c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2357c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2358c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2359c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2360c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()); 2361c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2362c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 2363c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2364c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2365c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2366c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2367c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2368c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2369c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2370c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2371c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2372c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2373c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2374c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2375c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2376c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2377c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2378c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2379c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2380c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2381c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2382c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2383c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2384c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2385c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = result.getPixel(px, py); 2386c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = reference.getPixel(px, py); 2387c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2388c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Other channels should trivially match to reference. 2389c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold))) 2390c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2391c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2392c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2393c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket continue; 2394c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2395c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2396c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Reference result is known to be a valid result, we can 2397c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // skip verification if thes results are equal 2398c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (resPix.x() != refPix.x()) 2399c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2400c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2401c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2402c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2403c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2404c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2405c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2406c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2407c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2408c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2409c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2410c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2411c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2412c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)); 2413c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2414c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 2415c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2416c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 2417c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2418c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 2419c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2420c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2421c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2422c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2423c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2424c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2425c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2426c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2427c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2428c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2429c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 2430c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2431c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 2432c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 2433c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2434c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2435c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2436c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2437c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2438c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2439c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x()); 2440c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2441c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2442c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2443c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2444c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2445c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2446c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2447c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2448c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2449c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2450c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2451c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2452c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2453c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureCompareDiff (const tcu::ConstPixelBufferAccess& result, 2454c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2455c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2456c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView& src, 2457c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2458c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2459c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TexComparePrecision& comparePrec, 2460c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2461c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3& nonShadowThreshold) 2462c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2463c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2464c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2465c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2466c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 2467c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 2468c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 2469c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2470c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2471c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2472c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2473c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getSize(); 2474c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2475c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 2476c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2477c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2478c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 2479c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2480c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2481c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2482c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2483c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2484c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2485c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2486c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2487c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2488c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2489c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2490c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2491c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2492c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2493c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2494c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2495c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2496c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2497c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2498c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2499c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = result.getPixel(px, py); 2500c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = reference.getPixel(px, py); 2501c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2502c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Other channels should trivially match to reference. 2503c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold))) 2504c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2505c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2506c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2507c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket continue; 2508c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2509c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2510c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Reference result is known to be a valid result, we can 2511c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // skip verification if thes results are equal 2512c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (resPix.x() != refPix.x()) 2513c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2514c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2515c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2516c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2517c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2518c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2519c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2520c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2521c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2522c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2523c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2524c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2525c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2526c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2527c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 2528c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2529c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 2530c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 2531c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2532c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 2533c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 2534c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2535c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec); 2536c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2537c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2538c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2539c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2540c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2541c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2542c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2543c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2544c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2545c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordO (projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2546c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 2547c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)); 2548c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo (triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2549c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 2550c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)); 2551c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo (triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2552c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 2553c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)); 2554c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec); 2555c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2556c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2557c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2558c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2559c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2560c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2561c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x()); 2562c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2563c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2564c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2565c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2566c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2567c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2568c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2569c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2570c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2571c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2572c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2573c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2574c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2575c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureCompareDiff (const tcu::ConstPixelBufferAccess& result, 2576c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2577c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2578c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView& src, 2579c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2580c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2581c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TexComparePrecision& comparePrec, 2582c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2583c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3& nonShadowThreshold) 2584c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2585c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2586c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2587c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2588c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 2589c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 2590c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 2591c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2592c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2593c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2594c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2595c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()); 2596c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2597c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 2598c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2599c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2600c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 2601c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2602c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2603c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2604c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2605c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2606c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2607c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2608c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2609c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2610c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2611c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2612c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2613c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2614c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2615c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2616c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2617c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2618c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2619c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2620c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2621c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = result.getPixel(px, py); 2622c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = reference.getPixel(px, py); 2623c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2624c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Other channels should trivially match to reference. 2625c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold))) 2626c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2627c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2628c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2629c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket continue; 2630c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2631c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2632c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Reference result is known to be a valid result, we can 2633c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // skip verification if thes results are equal 2634c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (resPix.x() != refPix.x()) 2635c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2636c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2637c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2638c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2639c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2640c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2641c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2642c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2643c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2644c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2645c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2646c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2647c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2648c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2649c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 2650c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2651c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 2652c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2653c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 2654c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2655c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 2656c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2657c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2658c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2659c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2660c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2661c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2662c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2663c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2664c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2665c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2666c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 2667c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2668c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 2669c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 2670c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2671c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2672c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2673c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2674c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2675c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2676c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x()); 2677c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2678c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2679c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2680c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2681c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2682c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2683c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2684c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2685c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2686c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2687c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2688c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2689c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2690c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// Mipmap generation comparison. 2691c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2692c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic int compareGenMipmapBilinear (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision) 2693c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2694c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures. 2695c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2696c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dst.getWidth()); 2697c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dst.getHeight()); 2698c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcW = float(src.getWidth()); 2699c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcH = float(src.getHeight()); 2700c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2701c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2702c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Translation to lookup verification parameters. 2703c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, 2704c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */); 2705c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::LookupPrecision lookupPrec; 2706c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2707c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorThreshold = precision.colorThreshold; 2708c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorMask = precision.colorMask; 2709c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.coordBits = tcu::IVec3(22); 2710c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.uvwBits = precision.filterBits; 2711c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2712c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 2713c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 2714c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2715c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 result = dst.getPixel(x, y); 2716c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cx = (float(x)+0.5f) / dstW * srcW; 2717c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cy = (float(y)+0.5f) / dstH * srcH; 2718c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result); 2719c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2720c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y); 2721c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2722c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2723c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2724c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2725c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2726c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2727c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2728c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic int compareGenMipmapBox (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision) 2729c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2730c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures. 2731c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2732c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dst.getWidth()); 2733c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dst.getHeight()); 2734c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcW = float(src.getWidth()); 2735c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcH = float(src.getHeight()); 2736c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2737c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2738c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Translation to lookup verification parameters. 2739c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, 2740c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */); 2741c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::LookupPrecision lookupPrec; 2742c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2743c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorThreshold = precision.colorThreshold; 2744c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorMask = precision.colorMask; 2745c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.coordBits = tcu::IVec3(22); 2746c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.uvwBits = precision.filterBits; 2747c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2748c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 2749c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 2750c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2751c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 result = dst.getPixel(x, y); 2752c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cx = deFloatFloor(float(x) / dstW * srcW) + 1.0f; 2753c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cy = deFloatFloor(float(y) / dstH * srcH) + 1.0f; 2754c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result); 2755c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2756c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y); 2757c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2758c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2759c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2760c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2761c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2762c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2763c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2764c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic int compareGenMipmapVeryLenient (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision) 2765c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2766c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures. 2767c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_UNREF(precision); 2768c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2769c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dst.getWidth()); 2770c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dst.getHeight()); 2771c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcW = float(src.getWidth()); 2772c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcH = float(src.getHeight()); 2773c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2774c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2775c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 2776c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 2777c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2778c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 result = dst.getPixel(x, y); 2779c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int minX = deFloorFloatToInt32(((float)x-0.5f) / dstW * srcW); 2780c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int minY = deFloorFloatToInt32(((float)y-0.5f) / dstH * srcH); 2781c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int maxX = deCeilFloatToInt32(((float)x+1.5f) / dstW * srcW); 2782c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int maxY = deCeilFloatToInt32(((float)y+1.5f) / dstH * srcH); 2783c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 minVal, maxVal; 2784c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk; 2785c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2786c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(minX < maxX && minY < maxY); 2787c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2788c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int ky = minY; ky <= maxY; ky++) 2789c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2790c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int kx = minX; kx <= maxX; kx++) 2791c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2792c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int sx = de::clamp(kx, 0, src.getWidth()-1); 2793c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int sy = de::clamp(ky, 0, src.getHeight()-1); 2794c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sample = src.getPixel(sx, sy); 2795c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2796c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (ky == minY && kx == minX) 2797c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2798c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket minVal = sample; 2799c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket maxVal = sample; 2800c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2801c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2802c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2803c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket minVal = min(sample, minVal); 2804c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket maxVal = max(sample, maxVal); 2805c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2806c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2807c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2808c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2809c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = boolAll(logicalAnd(lessThanEqual(minVal, result), lessThanEqual(result, maxVal))); 2810c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2811c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y); 2812c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2813c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2814c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2815c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2816c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2817c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2818c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2819c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter SiketqpTestResult compareGenMipmapResult (tcu::TestLog& log, const tcu::Texture2D& resultTexture, const tcu::Texture2D& level0Reference, const GenMipmapPrecision& precision) 2820c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2821c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpTestResult result = QP_TEST_RESULT_PASS; 2822c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2823c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Special comparison for level 0. 2824c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2825c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 threshold = select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask); 2826c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool level0Ok = tcu::floatThresholdCompare(log, "Level0", "Level 0", level0Reference.getLevel(0), resultTexture.getLevel(0), threshold, tcu::COMPARE_LOG_RESULT); 2827c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2828c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!level0Ok) 2829c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2830c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level 0 comparison failed!" << tcu::TestLog::EndMessage; 2831c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2832c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2833c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2834c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2835c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++) 2836c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2837c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess src = resultTexture.getLevel(levelNdx-1); 2838c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess dst = resultTexture.getLevel(levelNdx); 2839c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (dst.getWidth(), dst.getHeight()); 2840c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool levelOk = false; 2841c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2842c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try different comparisons in quality order. 2843c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2844c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2845c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2846c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision); 2847c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2848c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2849c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2850c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << " comparison to bilinear method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2851c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2852c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2853c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2854c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2855c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision); 2856c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2857c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2858c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2859c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << " comparison to box method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2860c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2861c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2862c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // At this point all high-quality methods have been used. 2863c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk && result == QP_TEST_RESULT_PASS) 2864c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_QUALITY_WARNING; 2865c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2866c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2867c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2868c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision); 2869c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2870c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2871c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2872c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << " appears to contain " << numFailed << " completely wrong pixels, failing case!" << tcu::TestLog::EndMessage; 2873c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2874c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2875c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2876c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2877c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2878c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx), string("Level ") + de::toString(levelNdx) + " result") 2879c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Result", "Result", dst); 2880c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2881c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2882c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2883c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2884c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2885c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2886c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2887c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return result; 2888c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2889c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2890c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter SiketqpTestResult compareGenMipmapResult (tcu::TestLog& log, const tcu::TextureCube& resultTexture, const tcu::TextureCube& level0Reference, const GenMipmapPrecision& precision) 2891c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2892c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpTestResult result = QP_TEST_RESULT_PASS; 2893c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2894c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const char* s_faceNames[] = { "-X", "+X", "-Y", "+Y", "-Z", "+Z" }; 2895c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_faceNames) == tcu::CUBEFACE_LAST); 2896c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2897c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Special comparison for level 0. 2898c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 2899c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2900c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::CubeFace face = tcu::CubeFace(faceNdx); 2901c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 threshold = select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask); 2902c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool level0Ok = tcu::floatThresholdCompare(log, 2903c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket ("Level0Face" + de::toString(faceNdx)).c_str(), 2904c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket (string("Level 0, face ") + s_faceNames[face]).c_str(), 2905c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket level0Reference.getLevelFace(0, face), 2906c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket resultTexture.getLevelFace(0, face), 2907c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket threshold, tcu::COMPARE_LOG_RESULT); 2908c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2909c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!level0Ok) 2910c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2911c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level 0, face " << s_faceNames[face] << " comparison failed!" << tcu::TestLog::EndMessage; 2912c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2913c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2914c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2915c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2916c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++) 2917c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2918c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 2919c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2920c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::CubeFace face = tcu::CubeFace(faceNdx); 2921c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const char* faceName = s_faceNames[face]; 2922c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess src = resultTexture.getLevelFace(levelNdx-1, face); 2923c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess dst = resultTexture.getLevelFace(levelNdx, face); 2924c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (dst.getWidth(), dst.getHeight()); 2925c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool levelOk = false; 2926c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2927c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try different comparisons in quality order. 2928c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2929c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2930c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2931c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision); 2932c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2933c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2934c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2935c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName << " comparison to bilinear method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2936c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2937c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2938c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2939c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2940c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision); 2941c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2942c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2943c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2944c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName <<" comparison to box method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2945c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2946c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2947c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // At this point all high-quality methods have been used. 2948c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk && result == QP_TEST_RESULT_PASS) 2949c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_QUALITY_WARNING; 2950c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2951c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2952c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2953c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision); 2954c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2955c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2956c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2957c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << ", face " << faceName << " appears to contain " << numFailed << " completely wrong pixels, failing case!" << tcu::TestLog::EndMessage; 2958c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2959c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2960c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2961c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2962c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2963c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx) + "Face" + de::toString(faceNdx), string("Level ") + de::toString(levelNdx) + ", face " + string(faceName) + " result") 2964c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Result", "Result", dst); 2965c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2966c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2967c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2968c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2969c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2970c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2971c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2972c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2973c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return result; 2974c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2975c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2976c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// Logging utilities. 2977c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2978c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstd::ostream& operator<< (std::ostream& str, const LogGradientFmt& fmt) 2979c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2980c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return str << "(R: " << fmt.valueMin->x() << " -> " << fmt.valueMax->x() << ", " 2981c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << "G: " << fmt.valueMin->y() << " -> " << fmt.valueMax->y() << ", " 2982c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << "B: " << fmt.valueMin->z() << " -> " << fmt.valueMax->z() << ", " 2983c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << "A: " << fmt.valueMin->w() << " -> " << fmt.valueMax->w() << ")"; 2984c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2985c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2986c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} // TextureTestUtil 2987c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} // glu 2988