From 06beb4d23816942e7ccc49c81530bb8702a6f336 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jarkko=20P=C3=B6yry?= Date: Fri, 6 Feb 2015 13:49:54 -0800 Subject: [PATCH] Optimize draw tests. - Skip multisample resolve if buffer is not multisampled. - Reject distant diamonds early in line rasterizer. - Preclear error masks to success color. - Reuse pixel buffer accesses, do not assume getAccess() is free. Change-Id: Ic60a6e0e4615c78739f9ccd62ae19567995c895d --- framework/common/tcuImageCompare.cpp | 62 ++++---- .../rrMultisamplePixelBufferAccess.cpp | 12 +- framework/referencerenderer/rrRasterizer.cpp | 38 ++++- modules/glshared/glsDrawTest.cpp | 169 ++++++++------------- modules/glshared/glsVertexArrayTests.cpp | 59 ++----- 5 files changed, 160 insertions(+), 180 deletions(-) diff --git a/framework/common/tcuImageCompare.cpp b/framework/common/tcuImageCompare.cpp index 3bae0ef..ced0145 100644 --- a/framework/common/tcuImageCompare.cpp +++ b/framework/common/tcuImageCompare.cpp @@ -89,18 +89,30 @@ void computeScaleAndBias (const ConstPixelBufferAccess& reference, const ConstPi static int findNumPositionDeviationFailingPixels (const PixelBufferAccess& errorMask, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue) { - const int width = reference.getWidth(); - const int height = reference.getHeight(); - const int depth = reference.getDepth(); - int numFailingPixels = 0; + const tcu::IVec4 okColor (0, 255, 0, 255); + const tcu::IVec4 errorColor (255, 0, 0, 255); + const int width = reference.getWidth(); + const int height = reference.getHeight(); + const int depth = reference.getDepth(); + int numFailingPixels = 0; + + // Accept pixels "sampling" over the image bounds pixels since "taps" could be anything + const int beginX = (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.x()) : (0); + const int beginY = (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.y()) : (0); + const int beginZ = (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.z()) : (0); + const int endX = (acceptOutOfBoundsAsAnyValue) ? (width - maxPositionDeviation.x()) : (0); + const int endY = (acceptOutOfBoundsAsAnyValue) ? (height - maxPositionDeviation.y()) : (0); + const int endZ = (acceptOutOfBoundsAsAnyValue) ? (depth - maxPositionDeviation.z()) : (0); TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth); - for (int z = 0; z < depth; z++) + tcu::clear(errorMask, okColor); + + for (int z = beginZ; z < endZ; z++) { - for (int y = 0; y < height; y++) + for (int y = beginY; y < endY; y++) { - for (int x = 0; x < width; x++) + for (int x = beginX; x < endX; x++) { const IVec4 refPix = reference.getPixelInt(x, y, z); const IVec4 cmpPix = result.getPixelInt(x, y, z); @@ -111,28 +123,13 @@ static int findNumPositionDeviationFailingPixels (const PixelBufferAccess& error const bool isOk = boolAll(lessThanEqual(diff, threshold)); if (isOk) - { - errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z); continue; - } - } - - // Accept over the image bounds pixels since they could be anything - - if (acceptOutOfBoundsAsAnyValue && - (x < maxPositionDeviation.x() || x + maxPositionDeviation.x() >= width || - y < maxPositionDeviation.y() || y + maxPositionDeviation.y() >= height || - z < maxPositionDeviation.z() || z + maxPositionDeviation.z() >= depth)) - { - errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z); - continue; } // Find matching pixels for both result and reference pixel { bool pixelFoundForReference = false; - bool pixelFoundForResult = false; // Find deviated result pixel for reference @@ -144,9 +141,19 @@ static int findNumPositionDeviationFailingPixels (const PixelBufferAccess& error const UVec4 diff = abs(refPix - deviatedCmpPix).cast(); const bool isOk = boolAll(lessThanEqual(diff, threshold)); - pixelFoundForReference |= isOk; + pixelFoundForReference = isOk; } + if (!pixelFoundForReference) + { + errorMask.setPixel(errorColor, x, y, z); + ++numFailingPixels; + continue; + } + } + { + bool pixelFoundForResult = false; + // Find deviated reference pixel for result for (int sz = de::max(0, z - maxPositionDeviation.z()); sz <= de::min(depth - 1, z + maxPositionDeviation.z()) && !pixelFoundForResult; ++sz) @@ -157,15 +164,14 @@ static int findNumPositionDeviationFailingPixels (const PixelBufferAccess& error const UVec4 diff = abs(cmpPix - deviatedRefPix).cast(); const bool isOk = boolAll(lessThanEqual(diff, threshold)); - pixelFoundForResult |= isOk; + pixelFoundForResult = isOk; } - if (pixelFoundForReference && pixelFoundForResult) - errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z); - else + if (!pixelFoundForResult) { - errorMask.setPixel(IVec4(0xff, 0, 0, 0xff), x, y, z); + errorMask.setPixel(errorColor, x, y, z); ++numFailingPixels; + continue; } } } diff --git a/framework/referencerenderer/rrMultisamplePixelBufferAccess.cpp b/framework/referencerenderer/rrMultisamplePixelBufferAccess.cpp index 65e0b6a..f7effbd 100644 --- a/framework/referencerenderer/rrMultisamplePixelBufferAccess.cpp +++ b/framework/referencerenderer/rrMultisamplePixelBufferAccess.cpp @@ -129,10 +129,16 @@ void resolveMultisampleColorBuffer (const tcu::PixelBufferAccess& dst, const Mul DE_ASSERT(dst.getWidth() == src.raw().getHeight()); DE_ASSERT(dst.getHeight() == src.raw().getDepth()); - float numSamplesInv = 1.0f / (float)src.getNumSamples(); - - for (int y = 0; y < dst.getHeight(); y++) + if (src.getNumSamples() == 1) + { + // fast-path for non-multisampled cases + tcu::copy(dst, src.toSinglesampleAccess()); + } + else { + const float numSamplesInv = 1.0f / (float)src.getNumSamples(); + + for (int y = 0; y < dst.getHeight(); y++) for (int x = 0; x < dst.getWidth(); x++) { tcu::Vec4 sum; diff --git a/framework/referencerenderer/rrRasterizer.cpp b/framework/referencerenderer/rrRasterizer.cpp index 855763d..9a8bff1 100644 --- a/framework/referencerenderer/rrRasterizer.cpp +++ b/framework/referencerenderer/rrRasterizer.cpp @@ -239,6 +239,43 @@ bool doesLineSegmentExitDiamond (const SubpixelLineSegment& line, const tcu::Vec const deInt64 halfPixel = 1ll << (RASTERIZER_SUBPIXEL_BITS-1); + // Reject distant diamonds early + { + const tcu::Vector u = line.direction(); + const tcu::Vector v = (diamondCenter - line.m_v0); + const deInt64 crossProduct = (u.x() * v.y() - u.y() * v.x()); + + // crossProduct = |p| |l| sin(theta) + // distanceFromLine = |p| sin(theta) + // => distanceFromLine = crossProduct / |l| + // + // |distanceFromLine| > C + // => distanceFromLine^2 > C^2 + // => crossProduct^2 / |l|^2 > C^2 + // => crossProduct^2 > |l|^2 * C^2 + + const deInt64 floorSqrtMaxInt64 = 3037000499LL; //!< floor(sqrt(MAX_INT64)) + + const deInt64 broadRejectDistance = 2 * halfPixel; + const deInt64 broadRejectDistanceSquared = broadRejectDistance * broadRejectDistance; + const bool crossProductOverflows = (crossProduct > floorSqrtMaxInt64 || crossProduct < -floorSqrtMaxInt64); + const deInt64 crossProductSquared = (crossProductOverflows) ? (0) : (crossProduct * crossProduct); // avoid overflow + const deInt64 lineLengthSquared = tcu::lengthSquared(u); + const bool limitValueCouldOverflow = ((64 - deClz64(lineLengthSquared)) + (64 - deClz64(broadRejectDistanceSquared))) > 63; + const deInt64 limitValue = (limitValueCouldOverflow) ? (0) : (lineLengthSquared * broadRejectDistanceSquared); // avoid overflow + + // only cross overflows + if (crossProductOverflows && !limitValueCouldOverflow) + return false; + + // both representable + if (!crossProductOverflows && !limitValueCouldOverflow) + { + if (crossProductSquared > limitValue) + return false; + } + } + const struct DiamondBound { tcu::Vector p0; @@ -281,7 +318,6 @@ bool doesLineSegmentExitDiamond (const SubpixelLineSegment& line, const tcu::Vec CORNER_EDGE_CASE_BEHAVIOR lineBehavior; // would a line segment going through this corner intersect with the region CORNER_START_CASE_BEHAVIOR startBehavior; // how the corner behaves if the start point at the corner CORNER_END_CASE_BEHAVIOR endBehavior; // how the corner behaves if the end point at the corner - } corners[] = { { tcu::Vector(0, -halfPixel), false, DiamondCorners::CORNER_EDGE_CASE_HIT_SECOND_QUARTER, DiamondCorners::CORNER_START_CASE_POSITIVE_Y_45, DiamondCorners::CORNER_END_CASE_DIRECTION_AND_SECOND_QUARTER}, diff --git a/modules/glshared/glsDrawTest.cpp b/modules/glshared/glsDrawTest.cpp index b82f261..05689db 100644 --- a/modules/glshared/glsDrawTest.cpp +++ b/modules/glshared/glsDrawTest.cpp @@ -76,21 +76,17 @@ const int MAX_RENDER_TARGET_SIZE = 512; static GLenum targetToGL (DrawTestSpec::Target target) { - DE_ASSERT(target < DrawTestSpec::TARGET_LAST); - static const GLenum targets[] = { GL_ELEMENT_ARRAY_BUFFER, // TARGET_ELEMENT_ARRAY = 0, GL_ARRAY_BUFFER // TARGET_ARRAY, }; - return targets[(int)target]; + return de::getSizedArrayElement(targets, (int)target); } static GLenum usageToGL (DrawTestSpec::Usage usage) { - DE_ASSERT(usage < DrawTestSpec::USAGE_LAST); - static const GLenum usages[] = { GL_DYNAMIC_DRAW, // USAGE_DYNAMIC_DRAW = 0, @@ -106,15 +102,12 @@ static GLenum usageToGL (DrawTestSpec::Usage usage) GL_DYNAMIC_READ, // USAGE_DYNAMIC_READ, GL_DYNAMIC_COPY // USAGE_DYNAMIC_COPY, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(usages) == DrawTestSpec::USAGE_LAST); - return usages[(int)usage]; + return de::getSizedArrayElement(usages, (int)usage); } static GLenum inputTypeToGL (DrawTestSpec::InputType type) { - DE_ASSERT(type < DrawTestSpec::INPUTTYPE_LAST); - static const GLenum types[] = { GL_FLOAT, // INPUTTYPE_FLOAT = 0, @@ -131,15 +124,12 @@ static GLenum inputTypeToGL (DrawTestSpec::InputType type) GL_UNSIGNED_INT_2_10_10_10_REV, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, GL_INT_2_10_10_10_REV // INPUTTYPE_INT_2_10_10_10, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == DrawTestSpec::INPUTTYPE_LAST); - return types[(int)type]; + return de::getSizedArrayElement(types, (int)type); } static std::string outputTypeToGLType (DrawTestSpec::OutputType type) { - DE_ASSERT(type < DrawTestSpec::OUTPUTTYPE_LAST); - static const char* types[] = { "float", // OUTPUTTYPE_FLOAT = 0, @@ -158,14 +148,13 @@ static std::string outputTypeToGLType (DrawTestSpec::OutputType type) "uvec3", // OUTPUTTYPE_UVEC3, "uvec4", // OUTPUTTYPE_UVEC4, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == DrawTestSpec::OUTPUTTYPE_LAST); - return types[type]; + return de::getSizedArrayElement(types, (int)type); } static GLenum primitiveToGL (DrawTestSpec::Primitive primitive) { - GLenum primitives[] = + static const GLenum primitives[] = { GL_POINTS, // PRIMITIVE_POINTS = 0, GL_TRIANGLES, // PRIMITIVE_TRIANGLES, @@ -179,22 +168,20 @@ static GLenum primitiveToGL (DrawTestSpec::Primitive primitive) GL_TRIANGLES_ADJACENCY, // PRIMITIVE_TRIANGLES_ADJACENCY GL_TRIANGLE_STRIP_ADJACENCY, // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(primitives) == DrawTestSpec::PRIMITIVE_LAST); - return primitives[(int)primitive]; + return de::getSizedArrayElement(primitives, (int)primitive); } static deUint32 indexTypeToGL (DrawTestSpec::IndexType indexType) { - GLenum indexTypes[] = + static const GLenum indexTypes[] = { GL_UNSIGNED_BYTE, // INDEXTYPE_BYTE = 0, GL_UNSIGNED_SHORT, // INDEXTYPE_SHORT, GL_UNSIGNED_INT, // INDEXTYPE_INT, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(indexTypes) == DrawTestSpec::INDEXTYPE_LAST); - return indexTypes[(int)indexType]; + return de::getSizedArrayElement(indexTypes, (int)indexType); } static bool inputTypeIsFloatType (DrawTestSpec::InputType type) @@ -291,9 +278,7 @@ static MethodInfo getMethodInfo (gls::DrawTestSpec::DrawMethod method) { true, false, true, false, true, false }, //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(infos) == DrawTestSpec::DRAWMETHOD_LAST); - DE_ASSERT((int)method < DE_LENGTH_OF_ARRAY(infos)); - return infos[(int)method]; + return de::getSizedArrayElement(infos, (int)method); } template @@ -2333,22 +2318,17 @@ bool DrawTestSpec::AttributeSpec::isBufferStrideAligned (void) const std::string DrawTestSpec::targetToString(Target target) { - DE_ASSERT(target < TARGET_LAST); - static const char* targets[] = { "element_array", // TARGET_ELEMENT_ARRAY = 0, "array" // TARGET_ARRAY, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(targets) == DrawTestSpec::TARGET_LAST); - return targets[(int)target]; + return de::getSizedArrayElement(targets, (int)target); } std::string DrawTestSpec::inputTypeToString(InputType type) { - DE_ASSERT(type < INPUTTYPE_LAST); - static const char* types[] = { "float", // INPUTTYPE_FLOAT = 0, @@ -2367,15 +2347,12 @@ std::string DrawTestSpec::inputTypeToString(InputType type) "unsigned_int2_10_10_10", // INPUTTYPE_UNSIGNED_INT_2_10_10_10, "int2_10_10_10" // INPUTTYPE_INT_2_10_10_10, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == DrawTestSpec::INPUTTYPE_LAST); - return types[(int)type]; + return de::getSizedArrayElement(types, (int)type); } std::string DrawTestSpec::outputTypeToString(OutputType type) { - DE_ASSERT(type < OUTPUTTYPE_LAST); - static const char* types[] = { "float", // OUTPUTTYPE_FLOAT = 0, @@ -2394,15 +2371,12 @@ std::string DrawTestSpec::outputTypeToString(OutputType type) "uvec3", // OUTPUTTYPE_UVEC3, "uvec4", // OUTPUTTYPE_UVEC4, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == DrawTestSpec::OUTPUTTYPE_LAST); - return types[(int)type]; + return de::getSizedArrayElement(types, (int)type); } std::string DrawTestSpec::usageTypeToString(Usage usage) { - DE_ASSERT(usage < USAGE_LAST); - static const char* usages[] = { "dynamic_draw", // USAGE_DYNAMIC_DRAW = 0, @@ -2418,29 +2392,23 @@ std::string DrawTestSpec::usageTypeToString(Usage usage) "dynamic_read", // USAGE_DYNAMIC_READ, "dynamic_copy", // USAGE_DYNAMIC_COPY, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(usages) == DrawTestSpec::USAGE_LAST); - return usages[(int)usage]; + return de::getSizedArrayElement(usages, (int)usage); } std::string DrawTestSpec::storageToString (Storage storage) { - DE_ASSERT(storage < STORAGE_LAST); - static const char* storages[] = { "user_ptr", // STORAGE_USER = 0, "buffer" // STORAGE_BUFFER, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(storages) == DrawTestSpec::STORAGE_LAST); - return storages[(int)storage]; + return de::getSizedArrayElement(storages, (int)storage); } std::string DrawTestSpec::primitiveToString (Primitive primitive) { - DE_ASSERT(primitive < PRIMITIVE_LAST); - static const char* primitives[] = { "points", // PRIMITIVE_POINTS , @@ -2455,30 +2423,24 @@ std::string DrawTestSpec::primitiveToString (Primitive primitive) "triangles_adjacency", // PRIMITIVE_TRIANGLES_ADJACENCY "triangle_strip_adjacency", // PRIMITIVE_TRIANGLE_STRIP_ADJACENCY }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(primitives) == DrawTestSpec::PRIMITIVE_LAST); - return primitives[(int)primitive]; + return de::getSizedArrayElement(primitives, (int)primitive); } std::string DrawTestSpec::indexTypeToString (IndexType type) { - DE_ASSERT(type < DrawTestSpec::INDEXTYPE_LAST); - static const char* indexTypes[] = { "byte", // INDEXTYPE_BYTE = 0, "short", // INDEXTYPE_SHORT, "int", // INDEXTYPE_INT, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(indexTypes) == DrawTestSpec::INDEXTYPE_LAST); - return indexTypes[(int)type]; + return de::getSizedArrayElement(indexTypes, (int)type); } std::string DrawTestSpec::drawMethodToString (DrawTestSpec::DrawMethod method) { - DE_ASSERT(method < DrawTestSpec::DRAWMETHOD_LAST); - static const char* methods[] = { "draw_arrays", //!< DRAWMETHOD_DRAWARRAYS @@ -2492,15 +2454,12 @@ std::string DrawTestSpec::drawMethodToString (DrawTestSpec::DrawMethod method) "draw_elements_instanced_base_vertex", //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX, "draw_range_elements_base_vertex", //!< DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(methods) == DrawTestSpec::DRAWMETHOD_LAST); - return methods[(int)method]; + return de::getSizedArrayElement(methods, (int)method); } int DrawTestSpec::inputTypeSize (InputType type) { - DE_ASSERT(type < INPUTTYPE_LAST); - static const int size[] = { sizeof(float), // INPUTTYPE_FLOAT = 0, @@ -2519,24 +2478,20 @@ int DrawTestSpec::inputTypeSize (InputType type) sizeof(deUint32) / 4, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, sizeof(deUint32) / 4 // INPUTTYPE_INT_2_10_10_10, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(size) == DrawTestSpec::INPUTTYPE_LAST); - return size[(int)type]; + return de::getSizedArrayElement(size, (int)type); } int DrawTestSpec::indexTypeSize (IndexType type) { - DE_ASSERT(type < INDEXTYPE_LAST); - static const int size[] = { sizeof(deUint8), // INDEXTYPE_BYTE, sizeof(deUint16), // INDEXTYPE_SHORT, sizeof(deUint32), // INDEXTYPE_INT, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(size) == DrawTestSpec::INDEXTYPE_LAST); - return size[(int)type]; + return de::getSizedArrayElement(size, (int)type); } std::string DrawTestSpec::getName (void) const @@ -3546,6 +3501,16 @@ static bool pixelNearLineIntersection (int x, int y, const tcu::Surface& target) return false; } +static inline bool colorsEqual (const tcu::RGBA& colorA, const tcu::RGBA& colorB, const tcu::IVec3& compareThreshold) +{ + enum + { + TCU_RGBA_RGB_MASK = tcu::RGBA::RED_MASK | tcu::RGBA::GREEN_MASK | tcu::RGBA::BLUE_MASK + }; + + return tcu::compareThresholdMasked(colorA, colorB, tcu::RGBA(compareThreshold.x(), compareThreshold.y(), compareThreshold.z(), 0), TCU_RGBA_RGB_MASK); +} + // search 3x3 are for matching color static bool pixelNeighborhoodContainsColor (const tcu::Surface& target, int x, int y, const tcu::RGBA& color, const tcu::IVec3& compareThreshold) { @@ -3556,12 +3521,8 @@ static bool pixelNeighborhoodContainsColor (const tcu::Surface& target, int x, i for (int dy = -1; dy < 2; dy++) for (int dx = -1; dx < 2; dx++) { - const tcu::RGBA targetCmpPixel = target.getPixel(x+dx, y+dy); - const int r = deAbs32(color.getRed() - targetCmpPixel.getRed()); - const int g = deAbs32(color.getGreen() - targetCmpPixel.getGreen()); - const int b = deAbs32(color.getBlue() - targetCmpPixel.getBlue()); - - if (r <= compareThreshold.x() && g <= compareThreshold.y() && b <= compareThreshold.z()) + const tcu::RGBA targetCmpPixel = target.getPixel(x+dx, y+dy); + if (colorsEqual(color, targetCmpPixel, compareThreshold)) return true; } @@ -3590,19 +3551,20 @@ static bool edgeRelaxedImageCompare (tcu::TestLog& log, const char* imageSetName { DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); - const tcu::IVec4 green (0, 255, 0, 255); - const tcu::IVec4 errorColor (255, 0, 0, 255); - const int width = reference.getWidth(); - const int height = reference.getHeight(); - tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height); - int numFailingPixels = 0; + const tcu::IVec4 green (0, 255, 0, 255); + const tcu::IVec4 red (255, 0, 0, 255); + const int width = reference.getWidth(); + const int height = reference.getHeight(); + tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height); + const tcu::PixelBufferAccess errorAccess = errorMask.getAccess(); + int numFailingPixels = 0; // clear errormask edges which would otherwise be transparent - tcu::clear(tcu::getSubregion(errorMask.getAccess(), 0, 0, width, 1), green); - tcu::clear(tcu::getSubregion(errorMask.getAccess(), 0, height-1, width, 1), green); - tcu::clear(tcu::getSubregion(errorMask.getAccess(), 0, 0, 1, height), green); - tcu::clear(tcu::getSubregion(errorMask.getAccess(), width-1, 0, 1, height), green); + tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green); + tcu::clear(tcu::getSubregion(errorAccess, 0, height-1, width, 1), green); + tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green); + tcu::clear(tcu::getSubregion(errorAccess, width-1, 0, 1, height), green); // skip edge pixels since coverage on edge cannot be verified @@ -3611,19 +3573,20 @@ static bool edgeRelaxedImageCompare (tcu::TestLog& log, const char* imageSetName { const tcu::RGBA refPixel = reference.getPixel(x, y); const tcu::RGBA screenPixel = result.getPixel(x, y); - const bool isOkReferencePixel = pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.) - const bool isOkScreenPixel = pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.) + const bool directMatch = colorsEqual(refPixel, screenPixel, compareThreshold); + const bool isOkReferencePixel = directMatch || pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.) + const bool isOkScreenPixel = directMatch || pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.) if (isOkScreenPixel && isOkReferencePixel) { // pixel valid, write greenish pixels to make the result image easier to read const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); - errorMask.getAccess().setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); + errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); } else if (!pixelNearEdge(x, y, reference, renderTargetThreshold)) { // non-edge pixel values must be within threshold of the reference values - errorMask.getAccess().setPixel(errorColor, x, y); + errorAccess.setPixel(red, x, y); ++numFailingPixels; } else @@ -3638,12 +3601,12 @@ static bool edgeRelaxedImageCompare (tcu::TestLog& log, const char* imageSetName { // pixel valid, write greenish pixels to make the result image easier to read const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); - errorMask.getAccess().setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); + errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); } else { // coverage does not match - errorMask.getAccess().setPixel(errorColor, x, y); + errorAccess.setPixel(red, x, y); ++numFailingPixels; } } @@ -3683,19 +3646,20 @@ static bool intersectionRelaxedLineImageCompare (tcu::TestLog& log, const char* { DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight()); - const tcu::IVec4 green (0, 255, 0, 255); - const tcu::IVec4 errorColor (255, 0, 0, 255); - const int width = reference.getWidth(); - const int height = reference.getHeight(); - tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height); - int numFailingPixels = 0; + const tcu::IVec4 green (0, 255, 0, 255); + const tcu::IVec4 red (255, 0, 0, 255); + const int width = reference.getWidth(); + const int height = reference.getHeight(); + tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), width, height); + const tcu::PixelBufferAccess errorAccess = errorMask.getAccess(); + int numFailingPixels = 0; // clear errormask edges which would otherwise be transparent - tcu::clear(tcu::getSubregion(errorMask.getAccess(), 0, 0, width, 1), green); - tcu::clear(tcu::getSubregion(errorMask.getAccess(), 0, height-1, width, 1), green); - tcu::clear(tcu::getSubregion(errorMask.getAccess(), 0, 0, 1, height), green); - tcu::clear(tcu::getSubregion(errorMask.getAccess(), width-1, 0, 1, height), green); + tcu::clear(tcu::getSubregion(errorAccess, 0, 0, width, 1), green); + tcu::clear(tcu::getSubregion(errorAccess, 0, height-1, width, 1), green); + tcu::clear(tcu::getSubregion(errorAccess, 0, 0, 1, height), green); + tcu::clear(tcu::getSubregion(errorAccess, width-1, 0, 1, height), green); // skip edge pixels since coverage on edge cannot be verified @@ -3704,20 +3668,21 @@ static bool intersectionRelaxedLineImageCompare (tcu::TestLog& log, const char* { const tcu::RGBA refPixel = reference.getPixel(x, y); const tcu::RGBA screenPixel = result.getPixel(x, y); - const bool isOkScreenPixel = pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.) - const bool isOkReferencePixel = pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.) + const bool directMatch = colorsEqual(refPixel, screenPixel, compareThreshold); + const bool isOkScreenPixel = directMatch || pixelNeighborhoodContainsColor(reference, x, y, screenPixel, compareThreshold); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.) + const bool isOkReferencePixel = directMatch || pixelNeighborhoodContainsColor(result, x, y, refPixel, compareThreshold); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.) if (isOkScreenPixel && isOkReferencePixel) { // pixel valid, write greenish pixels to make the result image easier to read const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); - errorMask.getAccess().setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); + errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); } else if (!pixelNearLineIntersection(x, y, reference) && !pixelNearLineIntersection(x, y, result)) { // non-intersection pixel values must be within threshold of the reference values - errorMask.getAccess().setPixel(errorColor, x, y); + errorAccess.setPixel(red, x, y); ++numFailingPixels; } else @@ -3733,12 +3698,12 @@ static bool intersectionRelaxedLineImageCompare (tcu::TestLog& log, const char* { // pixel valid, write greenish pixels to make the result image easier to read const deUint32 grayscaleValue = getVisualizationGrayscaleColor(screenPixel); - errorMask.getAccess().setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); + errorAccess.setPixel(tcu::UVec4(grayscaleValue, 255, grayscaleValue, 255), x, y); } else { // coverage does not match - errorMask.getAccess().setPixel(errorColor, x, y); + errorAccess.setPixel(red, x, y); ++numFailingPixels; } } diff --git a/modules/glshared/glsVertexArrayTests.cpp b/modules/glshared/glsVertexArrayTests.cpp index 919e702..8b6fcff 100644 --- a/modules/glshared/glsVertexArrayTests.cpp +++ b/modules/glshared/glsVertexArrayTests.cpp @@ -65,22 +65,17 @@ using namespace glw; // GL types std::string Array::targetToString(Target target) { - DE_ASSERT(target < TARGET_LAST); - static const char* targets[] = { "element_array", // TARGET_ELEMENT_ARRAY = 0, "array" // TARGET_ARRAY, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(targets) == Array::TARGET_LAST); - return targets[(int)target]; + return de::getSizedArrayElement(targets, (int)target); } std::string Array::inputTypeToString(InputType type) { - DE_ASSERT(type < INPUTTYPE_LAST); - static const char* types[] = { "float", // INPUTTYPE_FLOAT = 0, @@ -99,15 +94,12 @@ std::string Array::inputTypeToString(InputType type) "usigned_int2_10_10_10", // INPUTTYPE_UNSIGNED_INT_2_10_10_10, "int2_10_10_10" // INPUTTYPE_INT_2_10_10_10, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == Array::INPUTTYPE_LAST); - return types[(int)type]; + return de::getSizedArrayElement(types, (int)type); } std::string Array::outputTypeToString(OutputType type) { - DE_ASSERT(type < OUTPUTTYPE_LAST); - static const char* types[] = { "float", // OUTPUTTYPE_FLOAT = 0, @@ -126,15 +118,12 @@ std::string Array::outputTypeToString(OutputType type) "uvec3", // OUTPUTTYPE_UVEC3, "uvec4", // OUTPUTTYPE_UVEC4, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == Array::OUTPUTTYPE_LAST); - return types[(int)type]; + return de::getSizedArrayElement(types, (int)type); } std::string Array::usageTypeToString(Usage usage) { - DE_ASSERT(usage < USAGE_LAST); - static const char* usages[] = { "dynamic_draw", // USAGE_DYNAMIC_DRAW = 0, @@ -150,29 +139,23 @@ std::string Array::usageTypeToString(Usage usage) "dynamic_read", // USAGE_DYNAMIC_READ, "dynamic_copy", // USAGE_DYNAMIC_COPY, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(usages) == Array::USAGE_LAST); - return usages[(int)usage]; + return de::getSizedArrayElement(usages, (int)usage); } std::string Array::storageToString (Storage storage) { - DE_ASSERT(storage < STORAGE_LAST); - static const char* storages[] = { "user_ptr", // STORAGE_USER = 0, "buffer" // STORAGE_BUFFER, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(storages) == Array::STORAGE_LAST); - return storages[(int)storage]; + return de::getSizedArrayElement(storages, (int)storage); } std::string Array::primitiveToString (Primitive primitive) { - DE_ASSERT(primitive < PRIMITIVE_LAST); - static const char* primitives[] = { "points", // PRIMITIVE_POINTS , @@ -180,15 +163,12 @@ std::string Array::primitiveToString (Primitive primitive) "triangle_fan", // PRIMITIVE_TRIANGLE_FAN, "triangle_strip" // PRIMITIVE_TRIANGLE_STRIP, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(primitives) == Array::PRIMITIVE_LAST); - return primitives[(int)primitive]; + return de::getSizedArrayElement(primitives, (int)primitive); } int Array::inputTypeSize (InputType type) { - DE_ASSERT(type < INPUTTYPE_LAST); - static const int size[] = { sizeof(float), // INPUTTYPE_FLOAT = 0, @@ -207,9 +187,8 @@ int Array::inputTypeSize (InputType type) sizeof(deUint32) / 4, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, sizeof(deUint32) / 4 // INPUTTYPE_INT_2_10_10_10, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(size) == Array::INPUTTYPE_LAST); - return size[(int)type]; + return de::getSizedArrayElement(size, (int)type); } static bool inputTypeIsFloatType (Array::InputType type) @@ -648,21 +627,17 @@ void ContextArray::glBind (deUint32 loc) GLenum ContextArray::targetToGL (Array::Target target) { - DE_ASSERT(target < TARGET_LAST); - static const GLenum targets[] = { GL_ELEMENT_ARRAY_BUFFER, // TARGET_ELEMENT_ARRAY = 0, GL_ARRAY_BUFFER // TARGET_ARRAY, }; - return targets[(int)target]; + return de::getSizedArrayElement(targets, (int)target); } GLenum ContextArray::usageToGL (Array::Usage usage) { - DE_ASSERT(usage < USAGE_LAST); - static const GLenum usages[] = { GL_DYNAMIC_DRAW, // USAGE_DYNAMIC_DRAW = 0, @@ -678,15 +653,12 @@ GLenum ContextArray::usageToGL (Array::Usage usage) GL_DYNAMIC_READ, // USAGE_DYNAMIC_READ, GL_DYNAMIC_COPY // USAGE_DYNAMIC_COPY, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(usages) == Array::USAGE_LAST); - return usages[(int)usage]; + return de::getSizedArrayElement(usages, (int)usage); } GLenum ContextArray::inputTypeToGL (Array::InputType type) { - DE_ASSERT(type < INPUTTYPE_LAST); - static const GLenum types[] = { GL_FLOAT, // INPUTTYPE_FLOAT = 0, @@ -703,15 +675,12 @@ GLenum ContextArray::inputTypeToGL (Array::InputType type) GL_UNSIGNED_INT_2_10_10_10_REV, // INPUTTYPE_UNSIGNED_INT_2_10_10_10, GL_INT_2_10_10_10_REV // INPUTTYPE_INT_2_10_10_10, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == Array::INPUTTYPE_LAST); - return types[(int)type]; + return de::getSizedArrayElement(types, (int)type); } std::string ContextArray::outputTypeToGLType (Array::OutputType type) { - DE_ASSERT(type < OUTPUTTYPE_LAST); - static const char* types[] = { "float", // OUTPUTTYPE_FLOAT = 0, @@ -730,23 +699,21 @@ std::string ContextArray::outputTypeToGLType (Array::OutputType type) "uvec3", // OUTPUTTYPE_UVEC3, "uvec4", // OUTPUTTYPE_UVEC4, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(types) == Array::OUTPUTTYPE_LAST); - return types[type]; + return de::getSizedArrayElement(types, (int)type); } GLenum ContextArray::primitiveToGL (Array::Primitive primitive) { - GLenum primitives[] = + static const GLenum primitives[] = { GL_POINTS, // PRIMITIVE_POINTS = 0, GL_TRIANGLES, // PRIMITIVE_TRIANGLES, GL_TRIANGLE_FAN, // PRIMITIVE_TRIANGLE_FAN, GL_TRIANGLE_STRIP // PRIMITIVE_TRIANGLE_STRIP, }; - DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(primitives) == Array::PRIMITIVE_LAST); - return primitives[(int)primitive]; + return de::getSizedArrayElement(primitives, (int)primitive); } ContextArrayPack::ContextArrayPack (glu::RenderContext& renderCtx, sglr::Context& drawContext) -- 2.7.4