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 1359dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float posEps = 1.0f / float(1<<MIN_SUBPIXEL_BITS); 1360dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita 1361c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1362c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1363c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1364c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1365c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1366c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1367c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1368c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1369c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1370c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1371c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1372c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1373c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1374c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1375c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1376c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1377c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1378c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1379c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1380c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1381c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1382c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1383c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1384c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1385c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1386c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1387c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1388c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1389c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1390c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1391c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1392dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const bool tri0 = (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f; 1393dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const bool tri1 = (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f; 1394c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1395dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita bool isOk = false; 1396c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1397dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita DE_ASSERT(tri0 || tri1); 1398c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1399dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita // Pixel can belong to either of the triangles if it lies close enough to the edge. 1400dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++) 1401c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1402dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float triWx = triNdx ? dstW - wx : wx; 1403dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float triWy = triNdx ? dstH - wy : wy; 1404dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float triNx = triNdx ? 1.0f - nx : nx; 1405dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float triNy = triNdx ? 1.0f - ny : ny; 1406dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita 1407dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const tcu::Vec2 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1408dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)); 1409dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1410dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 1411dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1412dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 1413dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita 1414dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 1415dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita 1416dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita // Compute lod bounds across lodOffsets range. 1417dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1418dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita { 1419dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1420dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1421dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float nxo = wxo/dstW; 1422dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const float nyo = wyo/dstH; 1423dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita 1424dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 1425dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 1426dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 1427dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 1428dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 1429dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita 1430dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1431dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1432dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita } 1433dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita 1434dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1435dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix)) 1436dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita { 1437dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita isOk = true; 1438dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita break; 1439dcb5991811ed287fc4a72126663136a94eb7dc39Kalle Raita } 1440c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1441c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1442c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1443c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1444c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1445c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1446c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1447c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1448c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1449c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1450c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1451c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1452c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1453c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1454c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1455c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1456c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DView& src, 1457c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1458c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1459c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1460c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1461c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1462c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1463c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1464c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1465c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1466c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1467c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1468c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1469c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1470c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1471c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1472c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1473c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1474c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1475c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1476c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1477c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1478c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1479c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1480c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1481c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1482c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1483c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1484c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1485c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1486c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1487c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1488c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1489c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1490c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1491c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1492c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView& src, 1493c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1494c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1495c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1496c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1497c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1498c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1499c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1500c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1501c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1502c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1503c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1504c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1505c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1506c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1507c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1508c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1509c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1510c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1511c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1512c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1513c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1514c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1515c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1516c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1517c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1518c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1519c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1520c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1521c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1522c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1523c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1524c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1525c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1526c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1527c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1528c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1529c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1530c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView& baseView, 1531c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1532c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1533c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1534c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1535c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1536c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1537c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1538c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1539c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1540c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1541c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 1542c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1543c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 1544c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 1545c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 1546c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1547c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1548c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1549c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1550c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getSize(); 1551c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1552c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 1553c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1554c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1555c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 1556c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1557c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1558c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1559c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1560c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float posEps = 1.0f / float(1<<MIN_SUBPIXEL_BITS); 1561c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1562c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1563c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1564c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1565c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1566c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1567c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1568c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1569c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1570c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1571c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // \note Not strictly allowed by spec, but implementations do this in practice. 1572c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, -1), 1573c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, +1), 1574c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, -1), 1575c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, +1), 1576c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1577c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1578c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1579c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1580c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1581c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1582c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1583c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1584c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1585c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1586c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1587c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1588c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1589c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1590c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1591c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1592c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1593c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1594c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1595c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1596c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1597c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1598c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1599c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri0 = (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f; 1600c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri1 = (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f; 1601c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1602c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk = false; 1603c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1604c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(tri0 || tri1); 1605c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1606c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Pixel can belong to either of the triangles if it lies close enough to the edge. 1607c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++) 1608c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1609c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1610c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1611c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1612c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1613c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1614c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1615c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 1616c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 1617c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1618c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 1619c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 1620c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1621c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 1622c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 1623c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1624c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec); 1625c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1626c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1627c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1628c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1629c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1630c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1631c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1632c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1633c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1634c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordO (projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 1635c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 1636c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)); 1637c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo (triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 1638c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 1639c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)); 1640c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo (triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 1641c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 1642c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)); 1643c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec); 1644c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1645c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1646c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1647c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1648c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1649c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1650c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1651c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix)) 1652c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1653c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = true; 1654c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 1655c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1656c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1657c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1658c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1659c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1660c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1661c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1662c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1663c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1664c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1665c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1666c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1667c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1668c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1669c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1670c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1671c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1672c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView& src, 1673c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1674c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1675c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1676c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1677c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1678c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1679c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1680c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1681c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1682c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1683c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1684c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1685c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1686c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1687c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1688c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1689c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1690c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1691c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1692c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1693c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1694c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1695c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1696c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1697c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1698c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1699c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1700c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1701c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1702c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1703c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1704c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1705c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1706c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1707c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1708c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1709c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1710c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView& baseView, 1711c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1712c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1713c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1714c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1715c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1716c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1717c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1718c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1719c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1720c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1721c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 1722c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1723c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 1724c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 1725c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 1726c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1727c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1728c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1729c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1730c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec3 srcSize = tcu::IVec3(src.getWidth(), src.getHeight(), src.getDepth()); 1731c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1732c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 1733c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1734c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1735c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 1736c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1737c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1738c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1739c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1740c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float posEps = 1.0f / float(1<<MIN_SUBPIXEL_BITS); 1741c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1742c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1743c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1744c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1745c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1746c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1747c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1748c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1749c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1750c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1751c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1752c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1753c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1754c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1755c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1756c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1757c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1758c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1759c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1760c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1761c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1762c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1763c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1764c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1765c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1766c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1767c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1768c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1769c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1770c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1771c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1772c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1773c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri0 = (wx-posEps)/dstW + (wy-posEps)/dstH <= 1.0f; 1774c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri1 = (wx+posEps)/dstW + (wy+posEps)/dstH >= 1.0f; 1775c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1776c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk = false; 1777c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1778c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(tri0 || tri1); 1779c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1780c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Pixel can belong to either of the triangles if it lies close enough to the edge. 1781c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++) 1782c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1783c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1784c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1785c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1786c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1787c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1788c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1789c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 1790c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 1791c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx = tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 1792c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 1793c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 1794c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy = tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 1795c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 1796c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 1797c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1798c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDx.z(), coordDy.x(), coordDy.y(), coordDy.z(), lodPrec); 1799c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1800c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1801c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1802c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1803c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1804c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1805c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1806c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1807c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1808c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo = tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 1809c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 1810c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 1811c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo = tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 1812c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 1813c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 1814c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDxo.z(), coordDyo.x(), coordDyo.y(), coordDyo.z(), lodPrec); 1815c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1816c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1817c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1818c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1819c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1820c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1821c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1822c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix)) 1823c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1824c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = true; 1825c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 1826c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1827c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1828c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1829c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1830c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1831c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1832c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1833c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1834c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1835c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1836c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1837c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1838c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1839c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1840c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1841c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 1842c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 1843c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture3DView& src, 1844c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1845c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1846c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1847c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1848c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 1849c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1850c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 1851c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 1852c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 1853c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 1854c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1855c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 1856c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1857c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 1858c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 1859c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1860c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1861c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1862c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1863c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1864c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 1865c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1866c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 1867c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1868c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1869c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1870c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1871c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1872c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 1873c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1874c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 1875c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1876c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1877c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1878c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1879c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1880c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1881c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DArrayView& baseView, 1882c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1883c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1884c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1885c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1886c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1887c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1888c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1889c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1890c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1891c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1892c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DArrayView src = getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler); 1893c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1894c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]); 1895c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]); 1896c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1897c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 1898c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 1899c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 1900c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcSize = float(src.getWidth()); // For lod computation, thus #layers is ignored. 1901c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1902c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 1903c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 1904c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 1905c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 1906c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1907c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 1908c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1909c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 1910c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1911c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 1912c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1913c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 1914c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 1915c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 1916c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 1917c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 1918c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1919c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 1920c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1921c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 1922c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1923c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 1924c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 1925c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 1926c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1927c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 1928c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1929c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1930c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 1931c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1932c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 1933c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 1934c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1935c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 1936c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 1937c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 1938c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 1939c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1940c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 1941c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 1942c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 1943c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 1944c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 1945c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1946c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 1947c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)); 1948c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDx = triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize; 1949c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDy = triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx) * srcSize; 1950c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1951c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx, coordDy, lodPrec); 1952c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1953c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 1954c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 1955c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1956c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 1957c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 1958c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 1959c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 1960c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1961c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDxo = triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize; 1962c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float coordDyo = triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize; 1963c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec); 1964c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1965c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 1966c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 1967c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1968c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1969c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 1970c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 1971c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1972c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 1973c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 1974c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 1975c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 1976c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1977c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1978c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1979c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 1980c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1981c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 1982c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 1983c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1984c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 1985c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 1986c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 1987c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 1988c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView& baseView, 1989c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 1990c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 1991c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 1992c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 1993c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 1994c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 1995c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 1996c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 1997c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 1998c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1999c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView src = getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler); 2000c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2001c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 2002c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 2003c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 2004c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2005c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2006c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2007c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2008c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()).asFloat(); // For lod computation, thus #layers is ignored. 2009c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2010c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 2011c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2012c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2013c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 2014c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2015c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2016c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2017c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2018c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2019c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2020c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2021c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2022c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2023c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2024c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2025c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2026c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2027c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2028c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2029c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2030c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2031c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2032c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 2033c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 2034c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 2035c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2036c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2037c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2038c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2039c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2040c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2041c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 2042c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 2043c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2044c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2045c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2046c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2047c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2048c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2049c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2050c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2051c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2052c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2053c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2054c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2055c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2056c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2057c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 2058c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2059c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize; 2060c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2061c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize; 2062c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2063c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 2064c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2065c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2066c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2067c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2068c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2069c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2070c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2071c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2072c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2073c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2074c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize; 2075c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2076c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize; 2077c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 2078c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2079c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2080c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2081c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2082c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2083c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2084c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix); 2085c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2086c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2087c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2088c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2089c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2090c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2091c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2092c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2093c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2094c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2095c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2096c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2097c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2098c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 2099c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 2100c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture1DArrayView& src, 2101c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2102c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2103c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2104c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2105c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 2106c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2107c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 2108c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 2109c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 2110c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 2111c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2112c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 2113c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2114c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 2115c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 2116c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2117c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2118c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 2119c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2120c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 2121c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 2122c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2123c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2124c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2125c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 2126c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2127c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2128c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2129c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2130c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2131c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 2132c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2133c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2134c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 2135c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 2136c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView& src, 2137c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2138c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2139c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2140c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2141c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 2142c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2143c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 2144c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 2145c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 2146c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 2147c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2148c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 2149c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2150c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 2151c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog()); 2152c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2153c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2154c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 2155c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2156c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 2157c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 2158c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2159c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2160c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2161c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 2162c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2163c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2164c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2165c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2166c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2167c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 2168c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2169c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2170c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket//! Verifies texture lookup results and returns number of failed pixels. 2171c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureLookupDiff (const tcu::ConstPixelBufferAccess& result, 2172c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2173c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2174c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeArrayView& baseView, 2175c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2176c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2177c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2178c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec4& coordBits, 2179c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2180c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog* watchDog) 2181c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2182c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2183c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2184c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2185c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 2186c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeArrayView src = getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel), srcLevelStorage, sampleParams.sampler); 2187c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2188c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[4+0], texCoord[8+0], texCoord[12+0]); 2189c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[4+1], texCoord[8+1], texCoord[12+1]); 2190c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[4+2], texCoord[8+2], texCoord[12+2]); 2191c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 qq = tcu::Vec4(texCoord[0+3], texCoord[4+3], texCoord[8+3], texCoord[12+3]); 2192c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2193c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2194c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2195c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2196c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getSize(); 2197c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2198c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 2199c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2200c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2201c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 2202c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triQ[2] = { qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1) }; 2203c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2204c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2205c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2206c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2207c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float posEps = 1.0f / float((1<<4) + 1); // ES3 requires at least 4 subpixel bits. 2208c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2209c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2210c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2211c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2212c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2213c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2214c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2215c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2216c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2217c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2218c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // \note Not strictly allowed by spec, but implementations do this in practice. 2219c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, -1), 2220c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, +1), 2221c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, -1), 2222c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, +1), 2223c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2224c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2225c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2226c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2227c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2228c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2229c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Ugly hack, validation can take way too long at the moment. 2230c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (watchDog) 2231c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpWatchDog_touch(watchDog); 2232c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2233c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2234c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2235c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2236c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale; 2237c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2238c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try comparison to ideal reference first, and if that fails use slower verificator. 2239c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold))) 2240c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2241c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2242c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2243c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2244c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2245c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2246c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri0 = nx + ny - posEps <= 1.0f; 2247c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool tri1 = nx + ny + posEps >= 1.0f; 2248c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2249c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk = false; 2250c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2251c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(tri0 || tri1); 2252c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2253c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Pixel can belong to either of the triangles if it lies close enough to the edge. 2254c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int triNdx = (tri0?0:1); triNdx <= (tri1?1:0); triNdx++) 2255c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2256c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2257c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2258c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2259c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2260c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2261c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2262c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2263c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy), 2264c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triQ[triNdx], triW[triNdx], triNx, triNy)); 2265c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2266c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 2267c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 2268c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2269c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 2270c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 2271c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2272c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeCubeLodBoundsFromDerivates(coord.toWidth<3>(), coordDx, coordDy, srcSize, lodPrec); 2273c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2274c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2275c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2276c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2277c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2278c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2279c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2280c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2281c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2282c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordO (projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2283c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 2284c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)); 2285c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo (triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2286c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 2287c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)); 2288c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo (triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2289c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 2290c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)); 2291c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec); 2292c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2293c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2294c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2295c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2296c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2297c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2298c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2299c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coordBits, coord, clampedLod, resPix)) 2300c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2301c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = true; 2302c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket break; 2303c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2304c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2305c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2306c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2307c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2308c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2309c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2310c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2311c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2312c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2313c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2314c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2315c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2316c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2317c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2318c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketbool verifyTextureResult (tcu::TestContext& testCtx, 2319c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& result, 2320c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeArrayView& src, 2321c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2322c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2323c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LookupPrecision& lookupPrec, 2324c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec4& coordBits, 2325c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2326c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelFormat& pixelFormat) 2327c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2328c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::TestLog& log = testCtx.getLog(); 2329c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface reference (result.getWidth(), result.getHeight()); 2330c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (result.getWidth(), result.getHeight()); 2331c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailedPixels; 2332c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2333c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask); 2334c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2335c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams); 2336c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord, sampleParams, lookupPrec, coordBits, lodPrec, testCtx.getWatchDog()); 2337c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2338c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2339c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 2340c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2341c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 2342c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Rendered", "Rendered image", result); 2343c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2344c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailedPixels > 0) 2345c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2346c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 2347c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2348c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2349c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2350c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2351c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2352c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailedPixels == 0; 2353c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2354c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2355c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// Shadow lookup verification 2356c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2357c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureCompareDiff (const tcu::ConstPixelBufferAccess& result, 2358c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2359c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2360c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DView& src, 2361c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2362c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2363c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TexComparePrecision& comparePrec, 2364c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2365c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3& nonShadowThreshold) 2366c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2367c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2368c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2369c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2370c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[2+0], texCoord[4+0], texCoord[6+0]); 2371c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[2+1], texCoord[4+1], texCoord[6+1]); 2372c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2373c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2374c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2375c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2376c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()); 2377c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2378c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 2379c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2380c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2381c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2382c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2383c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2384c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2385c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2386c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2387c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2388c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2389c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2390c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2391c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2392c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2393c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2394c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2395c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2396c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2397c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2398c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2399c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2400c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2401c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = result.getPixel(px, py); 2402c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = reference.getPixel(px, py); 2403c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2404c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Other channels should trivially match to reference. 2405c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold))) 2406c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2407c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2408c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2409c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket continue; 2410c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2411c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2412c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Reference result is known to be a valid result, we can 2413c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // skip verification if thes results are equal 2414c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (resPix.x() != refPix.x()) 2415c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2416c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2417c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2418c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2419c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2420c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2421c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2422c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2423c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2424c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2425c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2426c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2427c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2428c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy)); 2429c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2430c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 2431c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2432c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 2433c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2434c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 2435c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2436c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2437c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2438c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2439c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2440c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2441c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2442c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2443c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2444c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2445c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 2446c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2447c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 2448c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 2449c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2450c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2451c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2452c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2453c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2454c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2455c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x()); 2456c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2457c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2458c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2459c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2460c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2461c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2462c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2463c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2464c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2465c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2466c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2467c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2468c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2469c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureCompareDiff (const tcu::ConstPixelBufferAccess& result, 2470c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2471c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2472c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TextureCubeView& src, 2473c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2474c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2475c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TexComparePrecision& comparePrec, 2476c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2477c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3& nonShadowThreshold) 2478c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2479c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2480c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2481c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2482c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 2483c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 2484c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 2485c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2486c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2487c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2488c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2489c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int srcSize = src.getSize(); 2490c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2491c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates per triangle. 2492c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2493c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2494c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 2495c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2496c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2497c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2498c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2499c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2500c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2501c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2502c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2503c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2504c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2505c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2506c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2507c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2508c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2509c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2510c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2511c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2512c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2513c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2514c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2515c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = result.getPixel(px, py); 2516c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = reference.getPixel(px, py); 2517c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2518c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Other channels should trivially match to reference. 2519c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold))) 2520c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2521c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2522c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2523c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket continue; 2524c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2525c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2526c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Reference result is known to be a valid result, we can 2527c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // skip verification if thes results are equal 2528c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (resPix.x() != refPix.x()) 2529c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2530c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2531c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2532c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2533c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2534c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2535c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2536c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2537c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2538c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2539c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2540c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2541c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2542c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2543c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 2544c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDx (triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2545c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy), 2546c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)); 2547c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDy (triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2548c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx), 2549c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)); 2550c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2551c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec); 2552c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2553c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2554c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2555c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2556c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2557c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2558c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2559c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2560c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2561c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordO (projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo), 2562c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo), 2563c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo)); 2564c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDxo (triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2565c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo), 2566c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)); 2567c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coordDyo (triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2568c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo), 2569c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)); 2570c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec); 2571c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2572c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2573c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2574c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2575c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2576c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2577c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x()); 2578c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2579c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2580c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2581c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2582c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2583c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2584c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2585c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2586c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2587c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2588c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2589c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2590c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2591c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketint computeTextureCompareDiff (const tcu::ConstPixelBufferAccess& result, 2592c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess& reference, 2593c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::PixelBufferAccess& errorMask, 2594c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Texture2DArrayView& src, 2595c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float* texCoord, 2596c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const ReferenceParams& sampleParams, 2597c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::TexComparePrecision& comparePrec, 2598c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::LodPrecision& lodPrec, 2599c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3& nonShadowThreshold) 2600c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2601c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); 2602c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight()); 2603c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2604c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sq = tcu::Vec4(texCoord[0+0], texCoord[3+0], texCoord[6+0], texCoord[9+0]); 2605c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 tq = tcu::Vec4(texCoord[0+1], texCoord[3+1], texCoord[6+1], texCoord[9+1]); 2606c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 rq = tcu::Vec4(texCoord[0+2], texCoord[3+2], texCoord[6+2], texCoord[9+2]); 2607c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2608c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight()); 2609c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dstSize.x()); 2610c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dstSize.y()); 2611c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight()); 2612c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2613c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Coordinates and lod per triangle. 2614c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triS[2] = { sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1) }; 2615c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triT[2] = { tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1) }; 2616c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triR[2] = { rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1) }; 2617c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 triW[2] = { sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1) }; 2618c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2619c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodBias ((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f); 2620c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2621c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2622c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2623c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodOffsets[] = 2624c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2625c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(-1, 0), 2626c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2(+1, 0), 2627c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, -1), 2628c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2( 0, +1), 2629c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket }; 2630c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2631c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::clear(errorMask, tcu::RGBA::green().toVec()); 2632c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2633c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int py = 0; py < result.getHeight(); py++) 2634c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2635c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int px = 0; px < result.getWidth(); px++) 2636c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2637c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 resPix = result.getPixel(px, py); 2638c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 refPix = reference.getPixel(px, py); 2639c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2640c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Other channels should trivially match to reference. 2641c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold))) 2642c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2643c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2644c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2645c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket continue; 2646c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2647c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2648c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Reference result is known to be a valid result, we can 2649c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // skip verification if thes results are equal 2650c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (resPix.x() != refPix.x()) 2651c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2652c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wx = (float)px + 0.5f; 2653c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wy = (float)py + 0.5f; 2654c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nx = wx / dstW; 2655c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float ny = wy / dstH; 2656c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2657c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int triNdx = nx + ny >= 1.0f ? 1 : 0; 2658c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWx = triNdx ? dstW - wx : wx; 2659c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triWy = triNdx ? dstH - wy : wy; 2660c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNx = triNdx ? 1.0f - nx : nx; 2661c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float triNy = triNdx ? 1.0f - ny : ny; 2662c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2663c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec3 coord (projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy), 2664c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy), 2665c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy)); 2666c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy), 2667c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) * srcSize.asFloat(); 2668c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx), 2669c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) * srcSize.asFloat(); 2670c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2671c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec); 2672c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2673c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Compute lod bounds across lodOffsets range. 2674c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++) 2675c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2676c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wxo = triWx + lodOffsets[lodOffsNdx].x(); 2677c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float wyo = triWy + lodOffsets[lodOffsNdx].y(); 2678c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nxo = wxo/dstW; 2679c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float nyo = wyo/dstH; 2680c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2681c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo), 2682c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) * srcSize.asFloat(); 2683c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo), 2684c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) * srcSize.asFloat(); 2685c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(), coordDyo.y(), lodPrec); 2686c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2687c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.x() = de::min(lodBounds.x(), lodO.x()); 2688c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lodBounds.y() = de::max(lodBounds.y(), lodO.y()); 2689c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2690c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2691c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec2 clampedLod = tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec); 2692c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord, clampedLod, sampleParams.ref, resPix.x()); 2693c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2694c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2695c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2696c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(tcu::RGBA::red().toVec(), px, py); 2697c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2698c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2699c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2700c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2701c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2702c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2703c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2704c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2705c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2706c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// Mipmap generation comparison. 2707c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2708c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic int compareGenMipmapBilinear (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision) 2709c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2710c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures. 2711c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2712c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dst.getWidth()); 2713c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dst.getHeight()); 2714c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcW = float(src.getWidth()); 2715c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcH = float(src.getHeight()); 2716c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2717c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2718c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Translation to lookup verification parameters. 2719c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, 2720c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */); 2721c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::LookupPrecision lookupPrec; 2722c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2723c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorThreshold = precision.colorThreshold; 2724c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorMask = precision.colorMask; 2725c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.coordBits = tcu::IVec3(22); 2726c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.uvwBits = precision.filterBits; 2727c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2728c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 2729c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 2730c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2731c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 result = dst.getPixel(x, y); 2732c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cx = (float(x)+0.5f) / dstW * srcW; 2733c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cy = (float(y)+0.5f) / dstH * srcH; 2734c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result); 2735c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2736c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y); 2737c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2738c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2739c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2740c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2741c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2742c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2743c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2744c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic int compareGenMipmapBox (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision) 2745c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2746c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures. 2747c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2748c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dst.getWidth()); 2749c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dst.getHeight()); 2750c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcW = float(src.getWidth()); 2751c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcH = float(src.getHeight()); 2752c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2753c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2754c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Translation to lookup verification parameters. 2755c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, 2756c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */); 2757c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::LookupPrecision lookupPrec; 2758c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2759c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorThreshold = precision.colorThreshold; 2760c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.colorMask = precision.colorMask; 2761c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.coordBits = tcu::IVec3(22); 2762c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket lookupPrec.uvwBits = precision.filterBits; 2763c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2764c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 2765c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 2766c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2767c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 result = dst.getPixel(x, y); 2768c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cx = deFloatFloor(float(x) / dstW * srcW) + 1.0f; 2769c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float cy = deFloatFloor(float(y) / dstH * srcH) + 1.0f; 2770c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool isOk = tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result); 2771c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2772c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y); 2773c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2774c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2775c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2776c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2777c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2778c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2779c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2780c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstatic int compareGenMipmapVeryLenient (const tcu::ConstPixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& errorMask, const GenMipmapPrecision& precision) 2781c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2782c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures. 2783c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_UNREF(precision); 2784c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2785c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstW = float(dst.getWidth()); 2786c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float dstH = float(dst.getHeight()); 2787c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcW = float(src.getWidth()); 2788c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const float srcH = float(src.getHeight()); 2789c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket int numFailed = 0; 2790c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2791c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int y = 0; y < dst.getHeight(); y++) 2792c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int x = 0; x < dst.getWidth(); x++) 2793c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2794c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 result = dst.getPixel(x, y); 2795c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int minX = deFloorFloatToInt32(((float)x-0.5f) / dstW * srcW); 2796c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int minY = deFloorFloatToInt32(((float)y-0.5f) / dstH * srcH); 2797c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int maxX = deCeilFloatToInt32(((float)x+1.5f) / dstW * srcW); 2798c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int maxY = deCeilFloatToInt32(((float)y+1.5f) / dstH * srcH); 2799c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Vec4 minVal, maxVal; 2800c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool isOk; 2801c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2802c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_ASSERT(minX < maxX && minY < maxY); 2803c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2804c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int ky = minY; ky <= maxY; ky++) 2805c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2806c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int kx = minX; kx <= maxX; kx++) 2807c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2808c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int sx = de::clamp(kx, 0, src.getWidth()-1); 2809c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int sy = de::clamp(ky, 0, src.getHeight()-1); 2810c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 sample = src.getPixel(sx, sy); 2811c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2812c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (ky == minY && kx == minX) 2813c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2814c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket minVal = sample; 2815c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket maxVal = sample; 2816c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2817c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2818c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2819c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket minVal = min(sample, minVal); 2820c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket maxVal = max(sample, maxVal); 2821c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2822c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2823c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2824c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2825c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket isOk = boolAll(logicalAnd(lessThanEqual(minVal, result), lessThanEqual(result, maxVal))); 2826c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2827c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y); 2828c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!isOk) 2829c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket numFailed += 1; 2830c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2831c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2832c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return numFailed; 2833c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2834c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2835c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter SiketqpTestResult compareGenMipmapResult (tcu::TestLog& log, const tcu::Texture2D& resultTexture, const tcu::Texture2D& level0Reference, const GenMipmapPrecision& precision) 2836c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2837c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpTestResult result = QP_TEST_RESULT_PASS; 2838c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2839c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Special comparison for level 0. 2840c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2841c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 threshold = select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask); 2842c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool level0Ok = tcu::floatThresholdCompare(log, "Level0", "Level 0", level0Reference.getLevel(0), resultTexture.getLevel(0), threshold, tcu::COMPARE_LOG_RESULT); 2843c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2844c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!level0Ok) 2845c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2846c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level 0 comparison failed!" << tcu::TestLog::EndMessage; 2847c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2848c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2849c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2850c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2851c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++) 2852c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2853c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess src = resultTexture.getLevel(levelNdx-1); 2854c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess dst = resultTexture.getLevel(levelNdx); 2855c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (dst.getWidth(), dst.getHeight()); 2856c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool levelOk = false; 2857c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2858c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try different comparisons in quality order. 2859c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2860c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2861c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2862c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision); 2863c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2864c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2865c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2866c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << " comparison to bilinear method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2867c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2868c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2869c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2870c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2871c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision); 2872c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2873c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2874c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2875c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << " comparison to box method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2876c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2877c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2878c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // At this point all high-quality methods have been used. 2879c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk && result == QP_TEST_RESULT_PASS) 2880c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_QUALITY_WARNING; 2881c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2882c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2883c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2884c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision); 2885c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2886c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2887c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2888c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << " appears to contain " << numFailed << " completely wrong pixels, failing case!" << tcu::TestLog::EndMessage; 2889c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2890c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2891c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2892c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2893c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2894c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx), string("Level ") + de::toString(levelNdx) + " result") 2895c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Result", "Result", dst); 2896c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2897c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2898c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2899c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2900c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2901c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2902c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2903c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return result; 2904c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2905c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2906c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter SiketqpTestResult compareGenMipmapResult (tcu::TestLog& log, const tcu::TextureCube& resultTexture, const tcu::TextureCube& level0Reference, const GenMipmapPrecision& precision) 2907c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2908c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket qpTestResult result = QP_TEST_RESULT_PASS; 2909c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2910c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket static const char* s_faceNames[] = { "-X", "+X", "-Y", "+Y", "-Z", "+Z" }; 2911c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_faceNames) == tcu::CUBEFACE_LAST); 2912c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2913c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Special comparison for level 0. 2914c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 2915c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2916c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::CubeFace face = tcu::CubeFace(faceNdx); 2917c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::Vec4 threshold = select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask); 2918c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const bool level0Ok = tcu::floatThresholdCompare(log, 2919c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket ("Level0Face" + de::toString(faceNdx)).c_str(), 2920c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket (string("Level 0, face ") + s_faceNames[face]).c_str(), 2921c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket level0Reference.getLevelFace(0, face), 2922c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket resultTexture.getLevelFace(0, face), 2923c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket threshold, tcu::COMPARE_LOG_RESULT); 2924c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2925c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!level0Ok) 2926c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2927c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level 0, face " << s_faceNames[face] << " comparison failed!" << tcu::TestLog::EndMessage; 2928c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2929c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2930c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2931c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2932c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++) 2933c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2934c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 2935c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2936c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::CubeFace face = tcu::CubeFace(faceNdx); 2937c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const char* faceName = s_faceNames[face]; 2938c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess src = resultTexture.getLevelFace(levelNdx-1, face); 2939c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const tcu::ConstPixelBufferAccess dst = resultTexture.getLevelFace(levelNdx, face); 2940c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket tcu::Surface errorMask (dst.getWidth(), dst.getHeight()); 2941c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket bool levelOk = false; 2942c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2943c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // Try different comparisons in quality order. 2944c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2945c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2946c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2947c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision); 2948c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2949c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2950c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2951c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName << " comparison to bilinear method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2952c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2953c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2954c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2955c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2956c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision); 2957c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2958c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2959c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2960c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName <<" comparison to box method failed, found " << numFailed << " invalid pixels." << tcu::TestLog::EndMessage; 2961c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2962c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2963c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket // At this point all high-quality methods have been used. 2964c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk && result == QP_TEST_RESULT_PASS) 2965c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_QUALITY_WARNING; 2966c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2967c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2968c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket { 2969c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision); 2970c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (numFailed == 0) 2971c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket levelOk = true; 2972c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket else 2973c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << ", face " << faceName << " appears to contain " << numFailed << " completely wrong pixels, failing case!" << tcu::TestLog::EndMessage; 2974c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2975c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2976c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2977c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket result = QP_TEST_RESULT_FAIL; 2978c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2979c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx) + "Face" + de::toString(faceNdx), string("Level ") + de::toString(levelNdx) + ", face " + string(faceName) + " result") 2980c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << tcu::TestLog::Image("Result", "Result", dst); 2981c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2982c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket if (!levelOk) 2983c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2984c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2985c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket log << tcu::TestLog::EndImageSet; 2986c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2987c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket } 2988c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2989c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return result; 2990c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 2991c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2992c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket// Logging utilities. 2993c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 2994c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siketstd::ostream& operator<< (std::ostream& str, const LogGradientFmt& fmt) 2995c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket{ 2996c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket return str << "(R: " << fmt.valueMin->x() << " -> " << fmt.valueMax->x() << ", " 2997c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << "G: " << fmt.valueMin->y() << " -> " << fmt.valueMax->y() << ", " 2998c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << "B: " << fmt.valueMin->z() << " -> " << fmt.valueMax->z() << ", " 2999c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket << "A: " << fmt.valueMin->w() << " -> " << fmt.valueMax->w() << ")"; 3000c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} 3001c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket 3002c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} // TextureTestUtil 3003c4eb6f3271a0bcd54835e666e836e3e72beebbd2Peter Siket} // glu 3004