You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.5 KiB
161 lines
4.5 KiB
/*------------------------------------------------------------------------- |
|
* drawElements Quality Program Tester Core |
|
* ---------------------------------------- |
|
* |
|
* Copyright 2014 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
*//*! |
|
* \file |
|
* \brief Internal utilities shared between TexLookup and TexCompare verifiers. |
|
*//*--------------------------------------------------------------------*/ |
|
|
|
#include "tcuTexVerifierUtil.hpp" |
|
#include "tcuFloat.hpp" |
|
|
|
namespace tcu |
|
{ |
|
namespace TexVerifierUtil |
|
{ |
|
|
|
float computeFloatingPointError (const float value, const int numAccurateBits) |
|
{ |
|
const int numGarbageBits = 23-numAccurateBits; |
|
const deUint32 mask = (1u<<numGarbageBits)-1u; |
|
const int exp = tcu::Float32(value).exponent(); |
|
|
|
return Float32::construct(+1, exp, (1u<<23) | mask).asFloat() - Float32::construct(+1, exp, 1u<<23).asFloat(); |
|
} |
|
|
|
float computeFixedPointError (const int numAccurateBits) |
|
{ |
|
return computeFloatingPointError(1.0f, numAccurateBits); |
|
} |
|
|
|
Vec2 computeNonNormalizedCoordBounds (const bool normalizedCoords, const int dim, const float coord, const int coordBits, const int uvBits) |
|
{ |
|
const float coordErr = computeFloatingPointError(coord, coordBits); |
|
const float minN = coord - coordErr; |
|
const float maxN = coord + coordErr; |
|
const float minA = normalizedCoords ? minN*float(dim) : minN; |
|
const float maxA = normalizedCoords ? maxN*float(dim) : maxN; |
|
const float minC = minA - computeFixedPointError(uvBits); |
|
const float maxC = maxA + computeFixedPointError(uvBits); |
|
|
|
DE_ASSERT(minC <= maxC); |
|
|
|
return Vec2(minC, maxC); |
|
} |
|
|
|
void getPossibleCubeFaces (const Vec3& coord, const IVec3& bits, CubeFace* faces, int& numFaces) |
|
{ |
|
const float x = coord.x(); |
|
const float y = coord.y(); |
|
const float z = coord.z(); |
|
const float ax = de::abs(x); |
|
const float ay = de::abs(y); |
|
const float az = de::abs(z); |
|
const float ex = computeFloatingPointError(x, bits.x()); |
|
const float ey = computeFloatingPointError(y, bits.y()); |
|
const float ez = computeFloatingPointError(z, bits.z()); |
|
|
|
numFaces = 0; |
|
|
|
if (ay+ey < ax-ex && az+ez < ax-ex) |
|
{ |
|
if (x >= ex) faces[numFaces++] = CUBEFACE_POSITIVE_X; |
|
if (x <= ex) faces[numFaces++] = CUBEFACE_NEGATIVE_X; |
|
} |
|
else if (ax+ex < ay-ey && az+ez < ay-ey) |
|
{ |
|
if (y >= ey) faces[numFaces++] = CUBEFACE_POSITIVE_Y; |
|
if (y <= ey) faces[numFaces++] = CUBEFACE_NEGATIVE_Y; |
|
} |
|
else if (ax+ex < az-ez && ay+ey < az-ez) |
|
{ |
|
if (z >= ez) faces[numFaces++] = CUBEFACE_POSITIVE_Z; |
|
if (z <= ez) faces[numFaces++] = CUBEFACE_NEGATIVE_Z; |
|
} |
|
else |
|
{ |
|
// One or more components are equal (or within error bounds). Allow all faces where major axis is not zero. |
|
if (ax > ex) |
|
{ |
|
faces[numFaces++] = CUBEFACE_NEGATIVE_X; |
|
faces[numFaces++] = CUBEFACE_POSITIVE_X; |
|
} |
|
|
|
if (ay > ey) |
|
{ |
|
faces[numFaces++] = CUBEFACE_NEGATIVE_Y; |
|
faces[numFaces++] = CUBEFACE_POSITIVE_Y; |
|
} |
|
|
|
if (az > ez) |
|
{ |
|
faces[numFaces++] = CUBEFACE_NEGATIVE_Z; |
|
faces[numFaces++] = CUBEFACE_POSITIVE_Z; |
|
} |
|
} |
|
} |
|
|
|
Sampler getUnnormalizedCoordSampler (const Sampler& sampler) |
|
{ |
|
Sampler copy = sampler; |
|
copy.normalizedCoords = false; |
|
return copy; |
|
} |
|
|
|
static inline int imod (int a, int b) |
|
{ |
|
int m = a % b; |
|
return m < 0 ? m + b : m; |
|
} |
|
|
|
static inline int mirror (int a) |
|
{ |
|
return a >= 0 ? a : -(1 + a); |
|
} |
|
|
|
int wrap (Sampler::WrapMode mode, int c, int size) |
|
{ |
|
switch (mode) |
|
{ |
|
// \note CL and GL modes are handled identically here, as verification process accounts for |
|
// accuracy differences caused by different methods (wrapping vs. denormalizing first). |
|
case tcu::Sampler::CLAMP_TO_BORDER: |
|
return deClamp32(c, -1, size); |
|
|
|
case tcu::Sampler::CLAMP_TO_EDGE: |
|
return deClamp32(c, 0, size-1); |
|
|
|
case tcu::Sampler::REPEAT_GL: |
|
case tcu::Sampler::REPEAT_CL: |
|
return imod(c, size); |
|
|
|
case tcu::Sampler::MIRRORED_ONCE: |
|
c = deClamp32(c, -size, size); |
|
// Fall-through |
|
|
|
case tcu::Sampler::MIRRORED_REPEAT_GL: |
|
case tcu::Sampler::MIRRORED_REPEAT_CL: |
|
return (size - 1) - mirror(imod(c, 2*size) - size); |
|
|
|
default: |
|
DE_ASSERT(DE_FALSE); |
|
return 0; |
|
} |
|
} |
|
} // TexVerifierUtil |
|
} // tcu
|
|
|