From 8ed28c1e05f2325dc4b20c8f471067b29188c82f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mika=20Isoj=C3=A4rvi?= Date: Thu, 21 Jan 2016 14:53:54 -0800 Subject: [PATCH] Snap values to 3x3 grid in vertex array tests This avoids cases where on small resolutions tests would fail because some geometry was not visible or hidden in both result and reference. Bug: 23495935 Change-Id: Iec3a26c3b85ec926d16068d5b20cfda8dd843b20 --- modules/glshared/glsVertexArrayTests.cpp | 60 ++++++++++++++++++++------------ modules/glshared/glsVertexArrayTests.hpp | 57 +++++++++++++++++++++++++----- 2 files changed, 85 insertions(+), 32 deletions(-) diff --git a/modules/glshared/glsVertexArrayTests.cpp b/modules/glshared/glsVertexArrayTests.cpp index 54cb855..6509f6d 100644 --- a/modules/glshared/glsVertexArrayTests.cpp +++ b/modules/glshared/glsVertexArrayTests.cpp @@ -1308,12 +1308,12 @@ class RandomArrayGenerator { public: static char* generateArray (int seed, GLValue min, GLValue max, int count, int componentCount, int stride, Array::InputType type); - static char* generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max); + static char* generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize); static char* generatePerQuad (int seed, int count, int componentCount, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max); private: template - static char* createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max); + static char* createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize); template static char* createPerQuads (int seed, int count, int componentCount, int stride, Array::Primitive primitive, T min, T max); static char* createQuadsPacked (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive); @@ -1413,50 +1413,50 @@ char* RandomArrayGenerator::generateArray (int seed, GLValue min, GLValue max, i return data; } -char* RandomArrayGenerator::generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max) +char* RandomArrayGenerator::generateQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, Array::InputType type, GLValue min, GLValue max, float gridSize) { char* data = DE_NULL; switch (type) { case Array::INPUTTYPE_FLOAT: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.fl, max.fl); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.fl, max.fl, gridSize); break; case Array::INPUTTYPE_FIXED: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.fi, max.fi); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.fi, max.fi, gridSize); break; case Array::INPUTTYPE_DOUBLE: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.d, max.d); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.d, max.d, gridSize); break; case Array::INPUTTYPE_BYTE: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.b, max.b); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.b, max.b, gridSize); break; case Array::INPUTTYPE_SHORT: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.s, max.s); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.s, max.s, gridSize); break; case Array::INPUTTYPE_UNSIGNED_BYTE: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.ub, max.ub); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.ub, max.ub, gridSize); break; case Array::INPUTTYPE_UNSIGNED_SHORT: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.us, max.us); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.us, max.us, gridSize); break; case Array::INPUTTYPE_UNSIGNED_INT: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.ui, max.ui); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.ui, max.ui, gridSize); break; case Array::INPUTTYPE_INT: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.i, max.i); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.i, max.i, gridSize); break; case Array::INPUTTYPE_HALF: - data = createQuads(seed, count, componentCount, offset, stride, primitive, min.h, max.h); + data = createQuads(seed, count, componentCount, offset, stride, primitive, min.h, max.h, gridSize); break; case Array::INPUTTYPE_INT_2_10_10_10: @@ -1545,13 +1545,20 @@ char* RandomArrayGenerator::createQuadsPacked (int seed, int count, int componen } template -char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max) +T roundTo (const T& step, const T& value) +{ + return value - (value % step); +} + +template +char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount, int offset, int stride, Array::Primitive primitive, T min, T max, float gridSize) { int componentStride = sizeof(T); int quadStride = 0; if (stride == 0) stride = componentCount * componentStride; + DE_ASSERT(stride >= componentCount * componentStride); switch (primitive) @@ -1576,6 +1583,11 @@ char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount { case Array::PRIMITIVE_TRIANGLES: { + const T minQuadSize = T::fromFloat(deFloatAbs(max.template to() - min.template to()) * gridSize); + const T minDiff = minValue() > minQuadSize + ? minValue() + : minQuadSize; + for (int quadNdx = 0; quadNdx < count; ++quadNdx) { T x1, x2; @@ -1585,22 +1597,22 @@ char* RandomArrayGenerator::createQuads (int seed, int count, int componentCount // attempt to find a good (i.e not extremely small) quad for (int attemptNdx = 0; attemptNdx < 4; ++attemptNdx) { - x1 = getRandom(rnd, min, max); - x2 = getRandom(rnd, minValue(), abs(max - x1)); + x1 = roundTo(minDiff, getRandom(rnd, min, max)); + x2 = roundTo(minDiff, getRandom(rnd, minDiff, abs(max - x1))); - y1 = getRandom(rnd, min, max); - y2 = getRandom(rnd, minValue(), abs(max - y1)); + y1 = roundTo(minDiff, getRandom(rnd, min, max)); + y2 = roundTo(minDiff, getRandom(rnd, minDiff, abs(max - y1))); - z = (componentCount > 2) ? (getRandom(rnd, min, max)) : (T::create(0)); - w = (componentCount > 3) ? (getRandom(rnd, min, max)) : (T::create(1)); + z = (componentCount > 2) ? roundTo(minDiff, (getRandom(rnd, min, max))) : (T::create(0)); + w = (componentCount > 3) ? roundTo(minDiff, (getRandom(rnd, min, max))) : (T::create(1)); // no additional components, all is good if (componentCount <= 2) break; // The result quad is too thin? - if ((deFloatAbs(x2.template to() + z.template to()) < minValue().template to()) || - (deFloatAbs(y2.template to() + w.template to()) < minValue().template to())) + if ((deFloatAbs(x2.template to() + z.template to()) < minDiff.template to()) || + (deFloatAbs(y2.template to() + w.template to()) < minDiff.template to())) continue; // all ok @@ -2075,6 +2087,8 @@ MultiVertexArrayTest::IterateResult MultiVertexArrayTest::iterate (void) const char* data = DE_NULL; const size_t stride = (arraySpec.stride == 0) ? (arraySpec.componentCount * Array::inputTypeSize(arraySpec.inputType)) : (arraySpec.stride); const size_t bufferSize = arraySpec.offset + stride * (m_spec.drawCount * primitiveSize - 1) + arraySpec.componentCount * Array::inputTypeSize(arraySpec.inputType); + // Snap values to at least 3x3 grid + const float gridSize = 3.0f / (float)(de::min(m_renderCtx.getRenderTarget().getWidth(), m_renderCtx.getRenderTarget().getHeight()) - 1); switch (m_spec.primitive) { @@ -2084,7 +2098,7 @@ MultiVertexArrayTest::IterateResult MultiVertexArrayTest::iterate (void) case Array::PRIMITIVE_TRIANGLES: if (arrayNdx == 0) { - data = RandomArrayGenerator::generateQuads(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.offset, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max); + data = RandomArrayGenerator::generateQuads(seed, m_spec.drawCount, arraySpec.componentCount, arraySpec.offset, arraySpec.stride, m_spec.primitive, arraySpec.inputType, arraySpec.min, arraySpec.max, gridSize); } else { diff --git a/modules/glshared/glsVertexArrayTests.hpp b/modules/glshared/glsVertexArrayTests.hpp index 25a04a3..b7539d4 100644 --- a/modules/glshared/glsVertexArrayTests.hpp +++ b/modules/glshared/glsVertexArrayTests.hpp @@ -31,6 +31,7 @@ #include "tcuTestLog.hpp" #include "gluShaderProgram.hpp" #include "deFloat16.h" +#include "deMath.h" #include "tcuFloat.hpp" #include "tcuPixelFormat.hpp" #include "sglrContext.hpp" @@ -236,17 +237,18 @@ private: class GLValue { public: - template class WrappedType { public: static WrappedType create (Type value) { WrappedType v; v.m_value = value; return v; } + static WrappedType fromFloat (float value) { WrappedType v; v.m_value = (Type)value; return v; } inline Type getValue (void) const { return m_value; } inline WrappedType operator+ (const WrappedType& other) const { return WrappedType::create((Type)(m_value + other.getValue())); } inline WrappedType operator* (const WrappedType& other) const { return WrappedType::create((Type)(m_value * other.getValue())); } inline WrappedType operator/ (const WrappedType& other) const { return WrappedType::create((Type)(m_value / other.getValue())); } + inline WrappedType operator% (const WrappedType& other) const { return WrappedType::create((Type)(m_value % other.getValue())); } inline WrappedType operator- (const WrappedType& other) const { return WrappedType::create((Type)(m_value - other.getValue())); } inline WrappedType& operator+= (const WrappedType& other) { m_value += other.getValue(); return *this; } @@ -268,27 +270,62 @@ public: Type m_value; }; - typedef WrappedType Short; - typedef WrappedType Ushort; + template + class WrappedFloatType + { + public: + static WrappedFloatType create (Type value) { WrappedFloatType v; v.m_value = value; return v; } + static WrappedFloatType fromFloat (float value) { WrappedFloatType v; v.m_value = (Type)value; return v; } + inline Type getValue (void) const { return m_value; } + + inline WrappedFloatType operator+ (const WrappedFloatType& other) const { return WrappedFloatType::create((Type)(m_value + other.getValue())); } + inline WrappedFloatType operator* (const WrappedFloatType& other) const { return WrappedFloatType::create((Type)(m_value * other.getValue())); } + inline WrappedFloatType operator/ (const WrappedFloatType& other) const { return WrappedFloatType::create((Type)(m_value / other.getValue())); } + inline WrappedFloatType operator% (const WrappedFloatType& other) const { return WrappedFloatType::create((Type)(deMod(m_value, other.getValue()))); } + inline WrappedFloatType operator- (const WrappedFloatType& other) const { return WrappedFloatType::create((Type)(m_value - other.getValue())); } + + inline WrappedFloatType& operator+= (const WrappedFloatType& other) { m_value += other.getValue(); return *this; } + inline WrappedFloatType& operator*= (const WrappedFloatType& other) { m_value *= other.getValue(); return *this; } + inline WrappedFloatType& operator/= (const WrappedFloatType& other) { m_value /= other.getValue(); return *this; } + inline WrappedFloatType& operator-= (const WrappedFloatType& other) { m_value -= other.getValue(); return *this; } + + inline bool operator== (const WrappedFloatType& other) const { return m_value == other.m_value; } + inline bool operator!= (const WrappedFloatType& other) const { return m_value != other.m_value; } + inline bool operator< (const WrappedFloatType& other) const { return m_value < other.m_value; } + inline bool operator> (const WrappedFloatType& other) const { return m_value > other.m_value; } + inline bool operator<= (const WrappedFloatType& other) const { return m_value <= other.m_value; } + inline bool operator>= (const WrappedFloatType& other) const { return m_value >= other.m_value; } + + inline operator Type (void) const { return m_value; } + template + inline T to (void) const { return (T)m_value; } + private: + Type m_value; + }; + + typedef WrappedType Short; + typedef WrappedType Ushort; - typedef WrappedType Byte; - typedef WrappedType Ubyte; + typedef WrappedType Byte; + typedef WrappedType Ubyte; - typedef WrappedType Float; - typedef WrappedType Double; + typedef WrappedFloatType Float; + typedef WrappedFloatType Double; - typedef WrappedType Int; - typedef WrappedType Uint; + typedef WrappedType Int; + typedef WrappedType Uint; class Half { public: static Half create (float value) { Half h; h.m_value = floatToHalf(value); return h; } + static Half fromFloat (float value) { Half h; h.m_value = floatToHalf(value); return h; } inline deFloat16 getValue (void) const { return m_value; } inline Half operator+ (const Half& other) const { return create(halfToFloat(m_value) + halfToFloat(other.getValue())); } inline Half operator* (const Half& other) const { return create(halfToFloat(m_value) * halfToFloat(other.getValue())); } inline Half operator/ (const Half& other) const { return create(halfToFloat(m_value) / halfToFloat(other.getValue())); } + inline Half operator% (const Half& other) const { return create(deFloatMod(halfToFloat(m_value), halfToFloat(other.getValue()))); } inline Half operator- (const Half& other) const { return create(halfToFloat(m_value) - halfToFloat(other.getValue())); } inline Half& operator+= (const Half& other) { m_value = floatToHalf(halfToFloat(other.getValue()) + halfToFloat(m_value)); return *this; } @@ -316,11 +353,13 @@ public: { public: static Fixed create (deInt32 value) { Fixed v; v.m_value = value; return v; } + static Fixed fromFloat (float value) { Fixed v; v.m_value = (deInt32)(value * 32768.0f); return v; } inline deInt32 getValue (void) const { return m_value; } inline Fixed operator+ (const Fixed& other) const { return create(m_value + other.getValue()); } inline Fixed operator* (const Fixed& other) const { return create(m_value * other.getValue()); } inline Fixed operator/ (const Fixed& other) const { return create(m_value / other.getValue()); } + inline Fixed operator% (const Fixed& other) const { return create(m_value % other.getValue()); } inline Fixed operator- (const Fixed& other) const { return create(m_value - other.getValue()); } inline Fixed& operator+= (const Fixed& other) { m_value += other.getValue(); return *this; } -- 2.7.4