1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Clipping tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es3fClippingTests.hpp"
25 #include "tcuRenderTarget.hpp"
26 #include "tcuTextureUtil.hpp"
27 #include "tcuImageCompare.hpp"
28 #include "tcuVectorUtil.hpp"
29 #include "deStringUtil.hpp"
30 #include "deRandom.hpp"
32 #include "sglrReferenceContext.hpp"
33 #include "sglrGLContext.hpp"
35 #include "glwEnums.hpp"
36 #include "glwDefs.hpp"
37 #include "glwFunctions.hpp"
39 using namespace glw; // GLint and other GL types
50 using tcu::PixelBufferAccess;
51 using tcu::ConstPixelBufferAccess;
54 static const tcu::Vec4 MASK_COLOR_OK = tcu::Vec4(0.0f, 0.1f, 0.0f, 1.0f);
55 static const tcu::Vec4 MASK_COLOR_DEV = tcu::Vec4(0.8f, 0.5f, 0.0f, 1.0f);
56 static const tcu::Vec4 MASK_COLOR_FAIL = tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f);
58 const int TEST_CANVAS_SIZE = 200;
59 const rr::WindowRectangle VIEWPORT_WHOLE (0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
60 const rr::WindowRectangle VIEWPORT_CENTER (TEST_CANVAS_SIZE/4, TEST_CANVAS_SIZE/4, TEST_CANVAS_SIZE/2, TEST_CANVAS_SIZE/2);
61 const rr::WindowRectangle VIEWPORT_CORNER (TEST_CANVAS_SIZE/2, TEST_CANVAS_SIZE/2, TEST_CANVAS_SIZE/2, TEST_CANVAS_SIZE/2);
64 const char* shaderSourceVertex = "#version 300 es\n"
65 "in highp vec4 a_position;\n"
66 "in highp vec4 a_color;\n"
67 "in highp float a_pointSize;\n"
68 "out highp vec4 varFragColor;\n"
71 " gl_Position = a_position;\n"
72 " gl_PointSize = a_pointSize;\n"
73 " varFragColor = a_color;\n"
75 const char* shaderSourceFragment = "#version 300 es\n"
76 "layout(location = 0) out mediump vec4 fragColor;"
77 "in highp vec4 varFragColor;\n"
80 " fragColor = varFragColor;\n"
83 inline bool isBlack (const tcu::IVec4& a)
85 return a.x() == 0 && a.y() == 0 && a.z() == 0;
88 inline bool isHalfFilled (const tcu::IVec4& a)
90 const tcu::IVec4 halfFilled (127, 0, 0, 0);
91 const tcu::IVec4 threshold (20, 256, 256, 256);
93 return tcu::boolAll(tcu::lessThanEqual(tcu::abs(a - halfFilled), threshold));
96 inline bool isLessThanHalfFilled (const tcu::IVec4& a)
98 const int halfFilled = 127;
99 const int threshold = 20;
101 return a.x() + threshold < halfFilled;
104 inline bool compareBlackNonBlackPixels (const tcu::IVec4& a, const tcu::IVec4& b)
106 return isBlack(a) == isBlack(b);
109 inline bool compareColoredPixels (const tcu::IVec4& a, const tcu::IVec4& b)
111 const bool aIsBlack = isBlack(a);
112 const bool bIsBlack = isBlack(b);
113 const tcu::IVec4 threshold(20, 20, 20, 0);
115 if (aIsBlack && bIsBlack)
117 if (aIsBlack != bIsBlack)
120 return tcu::boolAll(tcu::lessThanEqual(tcu::abs(a - b), threshold));
123 void blitImageOnBlackSurface(const ConstPixelBufferAccess& src, const PixelBufferAccess& dst)
125 const int height = src.getHeight();
126 const int width = src.getWidth();
128 for (int y = 0; y < height; y++)
129 for (int x = 0; x < width; x++)
131 const tcu::IVec4 cSrc = src.getPixelInt(x, y);
132 const tcu::IVec4 cDst = tcu::IVec4(cSrc.x(), cSrc.y(), cSrc.z(), 255);
134 dst.setPixel(cDst, x, y);
138 /*--------------------------------------------------------------------*//*!
139 * \brief Pixelwise comparison of two images.
140 * \note copied & modified from glsRasterizationTests
142 * Kernel radius defines maximum allowed distance. If radius is 0, only
143 * perfect match is allowed. Radius of 1 gives a 3x3 kernel. Pixels are
144 * equal if pixelCmp returns true..
146 * Return values: -1 = Perfect match
147 * 0 = Deviation within kernel
148 * >0 = Number of faulty pixels
149 *//*--------------------------------------------------------------------*/
150 inline int compareImages (tcu::TestLog& log, const ConstPixelBufferAccess& test, const ConstPixelBufferAccess& ref, const PixelBufferAccess& diffMask, int kernelRadius, bool (*pixelCmp)(const tcu::IVec4& a, const tcu::IVec4& b))
152 const int height = test.getHeight();
153 const int width = test.getWidth();
154 int deviatingPixels = 0;
155 int faultyPixels = 0;
156 int compareFailed = -1;
158 tcu::clear(diffMask, MASK_COLOR_OK);
160 for (int y = 0; y < height; y++)
162 for (int x = 0; x < width; x++)
164 const tcu::IVec4 cRef = ref.getPixelInt(x, y);
165 const tcu::IVec4 cTest = test.getPixelInt(x, y);
167 // Pixelwise match, no deviation or fault
168 if ((*pixelCmp)(cRef, cTest))
173 const int radius = kernelRadius;
174 bool foundRef = false;
175 bool foundTest = false;
177 // edges are considered a "deviation" too. The suitable pixel could be "behind" the edge
178 if (y < radius || x < radius || y + radius >= height || x + radius >= width)
186 for (int kY = y - radius; kY <= y + radius; kY++)
187 for (int kX = x - radius; kX <= x + radius; kX++)
189 if ((*pixelCmp)(cRef, test.getPixelInt(kX, kY)))
197 for (int kY = y - radius; kY <= y + radius; kY++)
198 for (int kX = x - radius; kX <= x + radius; kX++)
200 if ((*pixelCmp)(cTest, ref.getPixelInt(kX, kY)))
208 // A pixel is deviating if the reference color is found inside the kernel and (~= every pixel reference draws must be drawn by the gl too)
209 // the result color is found in the reference image inside the kernel (~= every pixel gl draws must be drawn by the reference too)
210 if (foundRef && foundTest)
212 diffMask.setPixel(MASK_COLOR_DEV, x, y);
213 if (compareFailed == -1)
220 diffMask.setPixel(MASK_COLOR_FAIL, x, y);
221 faultyPixels++; // The pixel is faulty if the color is not found
226 log << TestLog::Message << deviatingPixels << " deviating pixel(s) found." << TestLog::EndMessage;
227 log << TestLog::Message << faultyPixels << " faulty pixel(s) found." << TestLog::EndMessage;
229 return (compareFailed == 1 ? faultyPixels : compareFailed);
232 /*--------------------------------------------------------------------*//*!
233 * \brief Pixelwise comparison of two images.
235 * Kernel radius defines maximum allowed distance. If radius is 0, only
236 * perfect match is allowed. Radius of 1 gives a 3x3 kernel. Pixels are
237 * equal if they both are black, or both are non-black.
239 * Return values: -1 = Perfect match
240 * 0 = Deviation within kernel
241 * >0 = Number of faulty pixels
242 *//*--------------------------------------------------------------------*/
243 int compareBlackNonBlackImages (tcu::TestLog& log, const ConstPixelBufferAccess& test, const ConstPixelBufferAccess& ref, const PixelBufferAccess& diffMask, int kernelRadius)
245 return compareImages(log, test, ref, diffMask, kernelRadius, compareBlackNonBlackPixels);
248 /*--------------------------------------------------------------------*//*!
249 * \brief Pixelwise comparison of two images.
251 * Kernel radius defines maximum allowed distance. If radius is 0, only
252 * perfect match is allowed. Radius of 1 gives a 3x3 kernel. Pixels are
253 * equal if they both are black, or both are non-black with color values
254 * close to each other.
256 * Return values: -1 = Perfect match
257 * 0 = Deviation within kernel
258 * >0 = Number of faulty pixels
259 *//*--------------------------------------------------------------------*/
260 int compareColoredImages (tcu::TestLog& log, const ConstPixelBufferAccess& test, const ConstPixelBufferAccess& ref, const PixelBufferAccess& diffMask, int kernelRadius)
262 return compareImages(log, test, ref, diffMask, kernelRadius, compareColoredPixels);
265 /*--------------------------------------------------------------------*//*!
266 * \brief Overdraw check verification
268 * Check that image does not have at any point a
269 * pixel with red component value > 0.5
271 * Return values: false = area not filled, or leaking
272 *//*--------------------------------------------------------------------*/
273 bool checkHalfFilledImageOverdraw (tcu::TestLog& log, const tcu::RenderTarget& m_renderTarget, const ConstPixelBufferAccess& image, const PixelBufferAccess& output)
275 const int height = image.getHeight();
276 const int width = image.getWidth();
280 tcu::clear(output, MASK_COLOR_OK);
282 for (int y = 0; y < height; y++)
284 for (int x = 0; x < width; x++)
286 const tcu::IVec4 cTest = image.getPixelInt(x, y);
288 const bool pixelValid = isBlack(cTest) || isHalfFilled(cTest) || (m_renderTarget.getNumSamples() > 1 && isLessThanHalfFilled(cTest));
292 output.setPixel(MASK_COLOR_FAIL, x, y);
299 log << TestLog::Message << "Faulty pixel(s) found." << TestLog::EndMessage;
304 void checkPointSize (const glw::Functions& gl, float pointSize)
306 GLfloat pointSizeRange[2] = {0,0};
307 gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
308 if (pointSizeRange[1] < pointSize)
309 throw tcu::NotSupportedError("Maximum point size is too low for this test");
312 void checkLineWidth (const glw::Functions& gl, float lineWidth)
314 GLfloat lineWidthRange[2] = {0,0};
315 gl.getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);
316 if (lineWidthRange[1] < lineWidth)
317 throw tcu::NotSupportedError("Maximum line width is too low for this test");
320 tcu::Vec3 IVec3ToVec3 (const tcu::IVec3& v)
322 return tcu::Vec3((float)v.x(), (float)v.y(), (float)v.z());
325 bool pointOnTriangle (const tcu::IVec3& p, const tcu::IVec3& t0, const tcu::IVec3& t1, const tcu::IVec3& t2)
327 // Must be on the plane
328 const tcu::IVec3 n = tcu::cross(t1 - t0, t2 - t0);
329 const tcu::IVec3 d = (p - t0);
334 // Must be within the triangle area
335 if (deSign32(tcu::dot(n, tcu::cross(t1 - t0, p - t0))) == deSign32(tcu::dot(n, tcu::cross(t2 - t0, p - t0))))
337 if (deSign32(tcu::dot(n, tcu::cross(t2 - t1, p - t1))) == deSign32(tcu::dot(n, tcu::cross(t0 - t1, p - t1))))
339 if (deSign32(tcu::dot(n, tcu::cross(t0 - t2, p - t2))) == deSign32(tcu::dot(n, tcu::cross(t1 - t2, p - t2))))
345 bool pointsOnLine (const tcu::IVec2& t0, const tcu::IVec2& t1, const tcu::IVec2& t2)
347 return (t1 - t0).x() * (t2 - t0).y() - (t2 - t0).x() * (t1 - t0).y() == 0;
350 // returns true for cases where polygon is (almost) along xz or yz planes (normal.z < 0.1)
351 // \note[jarkko] Doesn't have to be accurate, just to detect some obviously bad cases
352 bool twoPointClippedTriangleInvisible(const tcu::Vec3& p, const tcu::IVec3& dir1, const tcu::IVec3& dir2)
354 // fixed-point-like coords
355 const deInt64 fixedScale = 64;
356 const deInt64 farValue = 1024;
357 const tcu::Vector<deInt64, 3> d1 = tcu::Vector<deInt64, 3>(dir1.x(), dir1.y(), dir1.z());
358 const tcu::Vector<deInt64, 3> d2 = tcu::Vector<deInt64, 3>(dir2.x(), dir2.y(), dir2.z());
359 const tcu::Vector<deInt64, 3> pfixed = tcu::Vector<deInt64, 3>(deFloorFloatToInt32(p.x() * fixedScale), deFloorFloatToInt32(p.y() * fixedScale), deFloorFloatToInt32(p.z() * fixedScale));
360 const tcu::Vector<deInt64, 3> normalDir = tcu::cross(d1*farValue - pfixed, d2*farValue - pfixed);
361 const deInt64 normalLen2 = tcu::lengthSquared(normalDir);
363 return (normalDir.z() * normalDir.z() - normalLen2/100) < 0;
366 std::string genClippingPointInfoString(const tcu::Vec4& p)
368 std::ostringstream msg;
370 if (p.x() < -p.w()) msg << "\t(-X clip)";
371 if (p.x() > p.w()) msg << "\t(+X clip)";
372 if (p.y() < -p.w()) msg << "\t(-Y clip)";
373 if (p.y() > p.w()) msg << "\t(+Y clip)";
374 if (p.z() < -p.w()) msg << "\t(-Z clip)";
375 if (p.z() > p.w()) msg << "\t(+Z clip)";
380 std::string genColorString(const tcu::Vec4& p)
382 const tcu::Vec4 white (1.0f, 1.0f, 1.0f, 1.0f);
383 const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
384 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
385 const tcu::Vec4 blue (0.0f, 0.0f, 1.0f, 1.0f);
387 if (p == white) return "(white)";
388 if (p == red) return "(red)";
389 if (p == yellow) return "(yellow)";
390 if (p == blue) return "(blue)";
394 class PositionColorShader : public sglr::ShaderProgram
402 PositionColorShader (void);
404 void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
405 void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;
408 PositionColorShader::PositionColorShader (void)
409 : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
410 << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
411 << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
412 << sglr::pdec::VertexAttribute("a_pointSize", rr::GENERICVECTYPE_FLOAT)
413 << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
414 << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
415 << sglr::pdec::VertexSource(shaderSourceVertex)
416 << sglr::pdec::FragmentSource(shaderSourceFragment))
420 void PositionColorShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
422 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
424 const int positionAttrLoc = 0;
425 const int colorAttrLoc = 1;
426 const int pointSizeAttrLoc = 2;
428 rr::VertexPacket& packet = *packets[packetNdx];
430 // Transform to position
431 packet.position = rr::readVertexAttribFloat(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx);
434 packet.pointSize = rr::readVertexAttribFloat(inputs[pointSizeAttrLoc], packet.instanceNdx, packet.vertexNdx).x();
437 packet.outputs[VARYINGLOC_COLOR] = rr::readVertexAttribFloat(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx);
441 void PositionColorShader::shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
443 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
445 rr::FragmentPacket& packet = packets[packetNdx];
447 for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
448 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, rr::readVarying<float>(packet, context, VARYINGLOC_COLOR, fragNdx));
452 class RenderTestCase : public TestCase
455 RenderTestCase (Context& context, const char* name, const char* description);
457 virtual void testRender (void) = DE_NULL;
458 virtual void init (void) { }
460 IterateResult iterate (void);
463 RenderTestCase::RenderTestCase (Context& context, const char* name, const char* description)
464 : TestCase (context, name, description)
468 RenderTestCase::IterateResult RenderTestCase::iterate (void)
470 const int width = m_context.getRenderTarget().getWidth();
471 const int height = m_context.getRenderTarget().getHeight();
473 m_testCtx.getLog() << TestLog::Message << "Render target size: " << width << "x" << height << TestLog::EndMessage;
474 if (width < TEST_CANVAS_SIZE || height < TEST_CANVAS_SIZE)
475 throw tcu::NotSupportedError(std::string("Render target size must be at least ") + de::toString(TEST_CANVAS_SIZE) + "x" + de::toString(TEST_CANVAS_SIZE));
477 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // success by default
483 class PointCase : public RenderTestCase
486 PointCase (Context& context, const char* name, const char* description, const tcu::Vec4* pointsBegin, const tcu::Vec4* pointsEnd, float pointSize, const rr::WindowRectangle& viewport);
489 void testRender (void);
492 const std::vector<tcu::Vec4> m_points;
493 const float m_pointSize;
494 const rr::WindowRectangle m_viewport;
497 PointCase::PointCase (Context& context, const char* name, const char* description, const tcu::Vec4* pointsBegin, const tcu::Vec4* pointsEnd, float pointSize, const rr::WindowRectangle& viewport)
498 : RenderTestCase(context, name, description)
499 , m_points (pointsBegin, pointsEnd)
500 , m_pointSize (pointSize)
501 , m_viewport (viewport)
505 void PointCase::init (void)
507 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
508 checkPointSize (gl, m_pointSize);
511 void PointCase::testRender (void)
515 const int numSamples = de::max(m_context.getRenderTarget().getNumSamples(), 1);
517 tcu::TestLog& log = m_testCtx.getLog();
518 sglr::GLContext glesContext (m_context.getRenderContext(), log, 0, tcu::IVec4(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE));
519 sglr::ReferenceContextLimits limits;
520 sglr::ReferenceContextBuffers buffers (m_context.getRenderTarget().getPixelFormat(), m_context.getRenderTarget().getDepthBits(), 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, numSamples);
521 sglr::ReferenceContext refContext (limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
522 PositionColorShader program;
523 tcu::Surface testSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
524 tcu::Surface refSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
525 sglr::Context* contexts[2] = {&glesContext, &refContext};
526 tcu::Surface* surfaces[2] = {&testSurface, &refSurface};
528 // log the purpose of the test
529 log << TestLog::Message << "Viewport: left=" << m_viewport.left << "\tbottom=" << m_viewport.bottom << "\twidth=" << m_viewport.width << "\theight=" << m_viewport.height << TestLog::EndMessage;
530 log << TestLog::Message << "Rendering points with point size " << m_pointSize << ". Coordinates:" << TestLog::EndMessage;
531 for (size_t ndx = 0; ndx < m_points.size(); ++ndx)
532 log << TestLog::Message
533 << "\tx=" << m_points[ndx].x()
534 << "\ty=" << m_points[ndx].y()
535 << "\tz=" << m_points[ndx].z()
536 << "\tw=" << m_points[ndx].w()
537 << "\t" << genClippingPointInfoString(m_points[ndx])
538 << TestLog::EndMessage;
540 for (int contextNdx = 0; contextNdx < 2; ++contextNdx)
542 sglr::Context& ctx = *contexts[contextNdx];
543 tcu::Surface& dstSurface = *surfaces[contextNdx];
544 const deUint32 programId = ctx.createProgram(&program);
545 const GLint positionLoc = ctx.getAttribLocation(programId, "a_position");
546 const GLint pointSizeLoc = ctx.getAttribLocation(programId, "a_pointSize");
547 const GLint colorLoc = ctx.getAttribLocation(programId, "a_color");
549 ctx.clearColor (0, 0, 0, 1);
550 ctx.clearDepthf (1.0f);
551 ctx.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
552 ctx.viewport (m_viewport.left, m_viewport.bottom, m_viewport.width, m_viewport.height);
553 ctx.useProgram (programId);
554 ctx.enableVertexAttribArray (positionLoc);
555 ctx.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &m_points[0]);
556 ctx.vertexAttrib1f (pointSizeLoc, m_pointSize);
557 ctx.vertexAttrib4f (colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
558 ctx.drawArrays (GL_POINTS, 0, (glw::GLsizei)m_points.size());
559 ctx.disableVertexAttribArray (positionLoc);
561 ctx.deleteProgram (programId);
564 ctx.readPixels(dstSurface, 0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
569 tcu::Surface diffMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
570 const int kernelRadius = 1;
573 log << TestLog::Message << "Comparing images... " << TestLog::EndMessage;
574 log << TestLog::Message << "Deviation within radius of " << kernelRadius << " is allowed." << TestLog::EndMessage;
576 faultyPixels = compareBlackNonBlackImages(log, testSurface.getAccess(), refSurface.getAccess(), diffMask.getAccess(), kernelRadius);
578 if (faultyPixels > 0)
580 log << TestLog::ImageSet("Images", "Image comparison")
581 << TestLog::Image("TestImage", "Test image", testSurface.getAccess())
582 << TestLog::Image("ReferenceImage", "Reference image", refSurface.getAccess())
583 << TestLog::Image("DifferenceMask", "Difference mask", diffMask.getAccess())
584 << TestLog::EndImageSet
585 << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
587 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
592 class LineRenderTestCase : public RenderTestCase
595 struct ColoredLineData
603 struct ColorlessLineData
608 LineRenderTestCase (Context& context, const char* name, const char* description, const ColoredLineData* linesBegin, const ColoredLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport);
609 LineRenderTestCase (Context& context, const char* name, const char* description, const ColorlessLineData* linesBegin, const ColorlessLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport);
611 virtual void verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess) = DE_NULL;
613 void testRender (void);
616 std::vector<ColoredLineData> convertToColoredLines (const ColorlessLineData* linesBegin, const ColorlessLineData* linesEnd);
618 const std::vector<ColoredLineData> m_lines;
619 const float m_lineWidth;
620 const rr::WindowRectangle m_viewport;
623 LineRenderTestCase::LineRenderTestCase (Context& context, const char* name, const char* description, const ColoredLineData* linesBegin, const ColoredLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport)
624 : RenderTestCase (context, name, description)
625 , m_lines (linesBegin, linesEnd)
626 , m_lineWidth (lineWidth)
627 , m_viewport (viewport)
631 LineRenderTestCase::LineRenderTestCase (Context& context, const char* name, const char* description, const ColorlessLineData* linesBegin, const ColorlessLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport)
632 : RenderTestCase (context, name, description)
633 , m_lines (convertToColoredLines(linesBegin, linesEnd))
634 , m_lineWidth (lineWidth)
635 , m_viewport (viewport)
639 void LineRenderTestCase::init (void)
641 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
642 checkLineWidth (gl, m_lineWidth);
645 void LineRenderTestCase::testRender (void)
649 const int numSamples = de::max(m_context.getRenderTarget().getNumSamples(), 1);
650 const int verticesPerLine = 2;
652 tcu::TestLog& log = m_testCtx.getLog();
653 sglr::GLContext glesContext (m_context.getRenderContext(), log, 0, tcu::IVec4(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE));
654 sglr::ReferenceContextLimits limits;
655 sglr::ReferenceContextBuffers buffers (m_context.getRenderTarget().getPixelFormat(), m_context.getRenderTarget().getDepthBits(), 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, numSamples);
656 sglr::ReferenceContext refContext (limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
657 PositionColorShader program;
658 tcu::Surface testSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
659 tcu::Surface refSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
660 sglr::Context* contexts[2] = {&glesContext, &refContext};
661 tcu::Surface* surfaces[2] = {&testSurface, &refSurface};
663 // log the purpose of the test
664 log << TestLog::Message << "Viewport: left=" << m_viewport.left << "\tbottom=" << m_viewport.bottom << "\twidth=" << m_viewport.width << "\theight=" << m_viewport.height << TestLog::EndMessage;
665 log << TestLog::Message << "Rendering lines with line width " << m_lineWidth << ". Coordinates:" << TestLog::EndMessage;
666 for (size_t ndx = 0; ndx < m_lines.size(); ++ndx)
668 const std::string fromProperties = genClippingPointInfoString(m_lines[ndx].p0);
669 const std::string toProperties = genClippingPointInfoString(m_lines[ndx].p1);
671 log << TestLog::Message << "\tfrom (x=" << m_lines[ndx].p0.x() << "\ty=" << m_lines[ndx].p0.y() << "\tz=" << m_lines[ndx].p0.z() << "\tw=" << m_lines[ndx].p0.w() << ")\t" << fromProperties << TestLog::EndMessage;
672 log << TestLog::Message << "\tto (x=" << m_lines[ndx].p1.x() << "\ty=" << m_lines[ndx].p1.y() << "\tz=" << m_lines[ndx].p1.z() << "\tw=" << m_lines[ndx].p1.w() << ")\t" << toProperties << TestLog::EndMessage;
673 log << TestLog::Message << TestLog::EndMessage;
677 for (int contextNdx = 0; contextNdx < 2; ++contextNdx)
679 sglr::Context& ctx = *contexts[contextNdx];
680 tcu::Surface& dstSurface = *surfaces[contextNdx];
681 const deUint32 programId = ctx.createProgram(&program);
682 const GLint positionLoc = ctx.getAttribLocation(programId, "a_position");
683 const GLint colorLoc = ctx.getAttribLocation(programId, "a_color");
685 ctx.clearColor (0, 0, 0, 1);
686 ctx.clearDepthf (1.0f);
687 ctx.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
688 ctx.viewport (m_viewport.left, m_viewport.bottom, m_viewport.width, m_viewport.height);
689 ctx.useProgram (programId);
690 ctx.enableVertexAttribArray (positionLoc);
691 ctx.enableVertexAttribArray (colorLoc);
692 ctx.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat[8]), &m_lines[0].p0);
693 ctx.vertexAttribPointer (colorLoc, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat[8]), &m_lines[0].c0);
694 ctx.lineWidth (m_lineWidth);
695 ctx.drawArrays (GL_LINES, 0, verticesPerLine * (glw::GLsizei)m_lines.size());
696 ctx.disableVertexAttribArray (positionLoc);
697 ctx.disableVertexAttribArray (colorLoc);
699 ctx.deleteProgram (programId);
702 ctx.readPixels(dstSurface, 0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
706 verifyImage(testSurface.getAccess(), refSurface.getAccess());
709 std::vector<LineRenderTestCase::ColoredLineData> LineRenderTestCase::convertToColoredLines(const ColorlessLineData* linesBegin, const ColorlessLineData* linesEnd)
711 std::vector<ColoredLineData> ret;
713 for (const ColorlessLineData* it = linesBegin; it != linesEnd; ++it)
718 r.c0 = tcu::Vec4(1, 1, 1, 1);
720 r.c1 = tcu::Vec4(1, 1, 1, 1);
728 class LineCase : public LineRenderTestCase
731 LineCase (Context& context, const char* name, const char* description, const LineRenderTestCase::ColorlessLineData* linesBegin, const LineRenderTestCase::ColorlessLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport, int searchKernelSize = 1);
733 void verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess);
736 const int m_searchKernelSize;
739 LineCase::LineCase (Context& context, const char* name, const char* description, const LineRenderTestCase::ColorlessLineData* linesBegin, const LineRenderTestCase::ColorlessLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport, int searchKernelSize)
740 : LineRenderTestCase (context, name, description, linesBegin, linesEnd, lineWidth, viewport)
741 , m_searchKernelSize (searchKernelSize)
745 void LineCase::verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess)
747 const int faultyLimit = 6;
750 tcu::TestLog& log = m_testCtx.getLog();
751 tcu::Surface diffMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
753 log << TestLog::Message << "Comparing images... " << TestLog::EndMessage;
754 log << TestLog::Message << "Deviation within radius of " << m_searchKernelSize << " is allowed." << TestLog::EndMessage;
755 log << TestLog::Message << faultyLimit << " faulty pixels are allowed." << TestLog::EndMessage;
757 faultyPixels = compareBlackNonBlackImages(log, testImageAccess, referenceImageAccess, diffMask.getAccess(), m_searchKernelSize);
759 if (faultyPixels > faultyLimit)
761 log << TestLog::ImageSet("Images", "Image comparison")
762 << TestLog::Image("TestImage", "Test image", testImageAccess)
763 << TestLog::Image("ReferenceImage", "Reference image", referenceImageAccess)
764 << TestLog::Image("DifferenceMask", "Difference mask", diffMask.getAccess())
765 << TestLog::EndImageSet
766 << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
768 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
772 class ColoredLineCase : public LineRenderTestCase
775 ColoredLineCase (Context& context, const char* name, const char* description, const LineRenderTestCase::ColoredLineData* linesBegin, const LineRenderTestCase::ColoredLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport);
777 void verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess);
780 ColoredLineCase::ColoredLineCase (Context& context, const char* name, const char* description, const LineRenderTestCase::ColoredLineData* linesBegin, const LineRenderTestCase::ColoredLineData* linesEnd, float lineWidth, const rr::WindowRectangle& viewport)
781 : LineRenderTestCase (context, name, description, linesBegin, linesEnd, lineWidth, viewport)
785 void ColoredLineCase::verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess)
787 const bool msaa = m_context.getRenderTarget().getNumSamples() > 1;
788 tcu::TestLog& log = m_testCtx.getLog();
792 const int kernelRadius = 1;
793 const int faultyLimit = 6;
796 tcu::Surface diffMask(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
798 log << TestLog::Message << "Comparing images... " << TestLog::EndMessage;
799 log << TestLog::Message << "Deviation within radius of " << kernelRadius << " is allowed." << TestLog::EndMessage;
800 log << TestLog::Message << faultyLimit << " faulty pixels are allowed." << TestLog::EndMessage;
802 faultyPixels = compareColoredImages(log, testImageAccess, referenceImageAccess, diffMask.getAccess(), kernelRadius);
804 if (faultyPixels > faultyLimit)
806 log << TestLog::ImageSet("Images", "Image comparison")
807 << TestLog::Image("TestImage", "Test image", testImageAccess)
808 << TestLog::Image("ReferenceImage", "Reference image", referenceImageAccess)
809 << TestLog::Image("DifferenceMask", "Difference mask", diffMask.getAccess())
810 << TestLog::EndImageSet
811 << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
813 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
818 const float threshold = 0.3f;
819 if (!tcu::fuzzyCompare(log, "Images", "", referenceImageAccess, testImageAccess, threshold, tcu::COMPARE_LOG_ON_ERROR))
820 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
824 class TriangleCaseBase : public RenderTestCase
837 TriangleCaseBase (Context& context, const char* name, const char* description, const TriangleData* polysBegin, const TriangleData* polysEnd, const rr::WindowRectangle& viewport);
839 virtual void verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess) = DE_NULL;
840 void testRender (void);
843 const std::vector<TriangleData> m_polys;
844 const rr::WindowRectangle m_viewport;
847 TriangleCaseBase::TriangleCaseBase (Context& context, const char* name, const char* description, const TriangleData* polysBegin, const TriangleData* polysEnd, const rr::WindowRectangle& viewport)
848 : RenderTestCase(context, name, description)
849 , m_polys (polysBegin, polysEnd)
850 , m_viewport (viewport)
854 void TriangleCaseBase::testRender (void)
858 const int numSamples = de::max(m_context.getRenderTarget().getNumSamples(), 1);
859 const int verticesPerTriangle = 3;
861 tcu::TestLog& log = m_testCtx.getLog();
862 sglr::GLContext glesContext (m_context.getRenderContext(), log, 0, tcu::IVec4(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE));
863 sglr::ReferenceContextLimits limits;
864 sglr::ReferenceContextBuffers buffers (m_context.getRenderTarget().getPixelFormat(), m_context.getRenderTarget().getDepthBits(), 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, numSamples);
865 sglr::ReferenceContext refContext (limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
866 PositionColorShader program;
867 tcu::Surface testSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
868 tcu::Surface refSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
869 sglr::Context* contexts[2] = {&glesContext, &refContext};
870 tcu::Surface* surfaces[2] = {&testSurface, &refSurface};
872 // log the purpose of the test
873 log << TestLog::Message << "Viewport: left=" << m_viewport.left << "\tbottom=" << m_viewport.bottom << "\twidth=" << m_viewport.width << "\theight=" << m_viewport.height << TestLog::EndMessage;
874 log << TestLog::Message << "Rendering triangles. Coordinates:" << TestLog::EndMessage;
875 for (size_t ndx = 0; ndx < m_polys.size(); ++ndx)
877 const std::string v0Properties = genClippingPointInfoString(m_polys[ndx].p0);
878 const std::string v1Properties = genClippingPointInfoString(m_polys[ndx].p1);
879 const std::string v2Properties = genClippingPointInfoString(m_polys[ndx].p2);
880 const std::string c0Properties = genColorString(m_polys[ndx].c0);
881 const std::string c1Properties = genColorString(m_polys[ndx].c1);
882 const std::string c2Properties = genColorString(m_polys[ndx].c2);
884 log << TestLog::Message << "\tv0 (x=" << m_polys[ndx].p0.x() << "\ty=" << m_polys[ndx].p0.y() << "\tz=" << m_polys[ndx].p0.z() << "\tw=" << m_polys[ndx].p0.w() << ")\t" << v0Properties << "\t" << c0Properties << TestLog::EndMessage;
885 log << TestLog::Message << "\tv1 (x=" << m_polys[ndx].p1.x() << "\ty=" << m_polys[ndx].p1.y() << "\tz=" << m_polys[ndx].p1.z() << "\tw=" << m_polys[ndx].p1.w() << ")\t" << v1Properties << "\t" << c1Properties << TestLog::EndMessage;
886 log << TestLog::Message << "\tv2 (x=" << m_polys[ndx].p2.x() << "\ty=" << m_polys[ndx].p2.y() << "\tz=" << m_polys[ndx].p2.z() << "\tw=" << m_polys[ndx].p2.w() << ")\t" << v2Properties << "\t" << c2Properties << TestLog::EndMessage;
887 log << TestLog::Message << TestLog::EndMessage;
891 for (int contextNdx = 0; contextNdx < 2; ++contextNdx)
893 sglr::Context& ctx = *contexts[contextNdx];
894 tcu::Surface& dstSurface = *surfaces[contextNdx];
895 const deUint32 programId = ctx.createProgram(&program);
896 const GLint positionLoc = ctx.getAttribLocation(programId, "a_position");
897 const GLint colorLoc = ctx.getAttribLocation(programId, "a_color");
899 ctx.clearColor (0, 0, 0, 1);
900 ctx.clearDepthf (1.0f);
901 ctx.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
902 ctx.viewport (m_viewport.left, m_viewport.bottom, m_viewport.width, m_viewport.height);
903 ctx.useProgram (programId);
904 ctx.enableVertexAttribArray (positionLoc);
905 ctx.enableVertexAttribArray (colorLoc);
906 ctx.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat[8]), &m_polys[0].p0);
907 ctx.vertexAttribPointer (colorLoc, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat[8]), &m_polys[0].c0);
908 ctx.drawArrays (GL_TRIANGLES, 0, verticesPerTriangle * (glw::GLsizei)m_polys.size());
909 ctx.disableVertexAttribArray (positionLoc);
910 ctx.disableVertexAttribArray (colorLoc);
912 ctx.deleteProgram (programId);
915 ctx.readPixels(dstSurface, 0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
918 verifyImage(testSurface.getAccess(), refSurface.getAccess());
921 class TriangleCase : public TriangleCaseBase
924 TriangleCase (Context& context, const char* name, const char* description, const TriangleData* polysBegin, const TriangleData* polysEnd, const rr::WindowRectangle& viewport);
926 void verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess);
929 TriangleCase::TriangleCase (Context& context, const char* name, const char* description, const TriangleData* polysBegin, const TriangleData* polysEnd, const rr::WindowRectangle& viewport)
930 : TriangleCaseBase(context, name, description, polysBegin, polysEnd, viewport)
934 void TriangleCase::verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess)
936 const int kernelRadius = 1;
937 const int faultyLimit = 6;
938 tcu::TestLog& log = m_testCtx.getLog();
939 tcu::Surface diffMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
942 log << TestLog::Message << "Comparing images... " << TestLog::EndMessage;
943 log << TestLog::Message << "Deviation within radius of " << kernelRadius << " is allowed." << TestLog::EndMessage;
944 log << TestLog::Message << faultyLimit << " faulty pixels are allowed." << TestLog::EndMessage;
946 faultyPixels = compareBlackNonBlackImages(log, testImageAccess, referenceImageAccess, diffMask.getAccess(), kernelRadius);
948 if (faultyPixels > faultyLimit)
950 log << TestLog::ImageSet("Images", "Image comparison")
951 << TestLog::Image("TestImage", "Test image", testImageAccess)
952 << TestLog::Image("ReferenceImage", "Reference image", referenceImageAccess)
953 << TestLog::Image("DifferenceMask", "Difference mask", diffMask.getAccess())
954 << TestLog::EndImageSet
955 << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
957 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
961 class TriangleAttributeCase : public TriangleCaseBase
964 TriangleAttributeCase (Context& context, const char* name, const char* description, const TriangleData* polysBegin, const TriangleData* polysEnd, const rr::WindowRectangle& viewport);
966 void verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess);
969 TriangleAttributeCase::TriangleAttributeCase (Context& context, const char* name, const char* description, const TriangleData* polysBegin, const TriangleData* polysEnd, const rr::WindowRectangle& viewport)
970 : TriangleCaseBase(context, name, description, polysBegin, polysEnd, viewport)
974 void TriangleAttributeCase::verifyImage (const tcu::ConstPixelBufferAccess& testImageAccess, const tcu::ConstPixelBufferAccess& referenceImageAccess)
976 const bool msaa = m_context.getRenderTarget().getNumSamples() > 1;
977 tcu::TestLog& log = m_testCtx.getLog();
981 const int kernelRadius = 1;
982 const int faultyLimit = 6;
984 tcu::Surface diffMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
986 log << TestLog::Message << "Comparing images... " << TestLog::EndMessage;
987 log << TestLog::Message << "Deviation within radius of " << kernelRadius << " is allowed." << TestLog::EndMessage;
988 log << TestLog::Message << faultyLimit << " faulty pixels are allowed." << TestLog::EndMessage;
989 faultyPixels = compareColoredImages(log, testImageAccess, referenceImageAccess, diffMask.getAccess(), kernelRadius);
991 if (faultyPixels > faultyLimit)
993 log << TestLog::ImageSet("Images", "Image comparison")
994 << TestLog::Image("TestImage", "Test image", testImageAccess)
995 << TestLog::Image("ReferenceImage", "Reference image", referenceImageAccess)
996 << TestLog::Image("DifferenceMask", "Difference mask", diffMask.getAccess())
997 << TestLog::EndImageSet
998 << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
1000 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
1005 const float threshold = 0.3f;
1006 if (!tcu::fuzzyCompare(log, "Images", "", referenceImageAccess, testImageAccess, threshold, tcu::COMPARE_LOG_ON_ERROR))
1007 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
1011 class FillTest : public RenderTestCase
1014 FillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport);
1016 virtual void render (sglr::Context& ctx) = DE_NULL;
1017 void testRender (void);
1020 const rr::WindowRectangle m_viewport;
1023 FillTest::FillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport)
1024 : RenderTestCase(context, name, description)
1025 , m_viewport (viewport)
1029 void FillTest::testRender (void)
1033 const int numSamples = 1;
1035 tcu::TestLog& log = m_testCtx.getLog();
1036 sglr::GLContext glesContext (m_context.getRenderContext(), log, 0, tcu::IVec4(0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE));
1037 sglr::ReferenceContextLimits limits;
1038 sglr::ReferenceContextBuffers buffers (m_context.getRenderTarget().getPixelFormat(), m_context.getRenderTarget().getDepthBits(), 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE, numSamples);
1039 sglr::ReferenceContext refContext (limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
1040 tcu::Surface testSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1041 tcu::Surface refSurface (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1043 render(glesContext);
1044 glesContext.readPixels(testSurface, 0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1047 refContext.readPixels(refSurface, 0, 0, TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1052 tcu::Surface outputImage(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1054 log << TestLog::Message << "Checking for overdraw " << TestLog::EndMessage;
1055 overdrawOk = checkHalfFilledImageOverdraw(log, m_context.getRenderTarget(), testSurface.getAccess(), outputImage.getAccess());
1059 log << TestLog::ImageSet("Images", "Image comparison")
1060 << TestLog::Image("TestImage", "Test image", testSurface.getAccess())
1061 << TestLog::Image("InvalidPixels", "Invalid pixels", outputImage.getAccess())
1062 << TestLog::EndImageSet
1063 << tcu::TestLog::Message << "Got overdraw." << tcu::TestLog::EndMessage;
1065 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got overdraw");
1069 // compare & check missing pixels
1071 const int kernelRadius = 1;
1072 tcu::Surface diffMask (TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
1075 log << TestLog::Message << "Comparing images... " << TestLog::EndMessage;
1076 log << TestLog::Message << "Deviation within radius of " << kernelRadius << " is allowed." << TestLog::EndMessage;
1078 blitImageOnBlackSurface(refSurface.getAccess(), refSurface.getAccess()); // makes images look right in Candy
1080 faultyPixels = compareBlackNonBlackImages(log, testSurface.getAccess(), refSurface.getAccess(), diffMask.getAccess(), kernelRadius);
1082 if (faultyPixels > 0)
1084 log << TestLog::ImageSet("Images", "Image comparison")
1085 << TestLog::Image("TestImage", "Test image", testSurface.getAccess())
1086 << TestLog::Image("ReferenceImage", "Reference image", refSurface.getAccess())
1087 << TestLog::Image("DifferenceMask", "Difference mask", diffMask.getAccess())
1088 << TestLog::EndImageSet
1089 << tcu::TestLog::Message << "Got " << faultyPixels << " faulty pixel(s)." << tcu::TestLog::EndMessage;
1091 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got faulty pixels");
1096 class TriangleFillTest : public FillTest
1109 TriangleFillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport);
1111 void render (sglr::Context& ctx);
1114 std::vector<FillTriangle> m_triangles;
1117 TriangleFillTest::TriangleFillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport)
1118 : FillTest(context, name, description, viewport)
1122 void TriangleFillTest::render (sglr::Context& ctx)
1124 const int verticesPerTriangle = 3;
1125 PositionColorShader program;
1126 const deUint32 programId = ctx.createProgram(&program);
1127 const GLint positionLoc = ctx.getAttribLocation(programId, "a_position");
1128 const GLint colorLoc = ctx.getAttribLocation(programId, "a_color");
1129 tcu::TestLog& log = m_testCtx.getLog();
1131 // log the purpose of the test
1132 log << TestLog::Message << "Viewport: left=" << m_viewport.left << "\tbottom=" << m_viewport.bottom << "\twidth=" << m_viewport.width << "\theight=" << m_viewport.height << TestLog::EndMessage;
1133 log << TestLog::Message << "Rendering triangles. Coordinates:" << TestLog::EndMessage;
1134 for (size_t ndx = 0; ndx < m_triangles.size(); ++ndx)
1136 const std::string v0Properties = genClippingPointInfoString(m_triangles[ndx].v0);
1137 const std::string v1Properties = genClippingPointInfoString(m_triangles[ndx].v1);
1138 const std::string v2Properties = genClippingPointInfoString(m_triangles[ndx].v2);
1140 log << TestLog::Message << "\tv0 (x=" << m_triangles[ndx].v0.x() << "\ty=" << m_triangles[ndx].v0.y() << "\tz=" << m_triangles[ndx].v0.z() << "\tw=" << m_triangles[ndx].v0.w() << ")\t" << v0Properties << TestLog::EndMessage;
1141 log << TestLog::Message << "\tv1 (x=" << m_triangles[ndx].v1.x() << "\ty=" << m_triangles[ndx].v1.y() << "\tz=" << m_triangles[ndx].v1.z() << "\tw=" << m_triangles[ndx].v1.w() << ")\t" << v1Properties << TestLog::EndMessage;
1142 log << TestLog::Message << "\tv2 (x=" << m_triangles[ndx].v2.x() << "\ty=" << m_triangles[ndx].v2.y() << "\tz=" << m_triangles[ndx].v2.z() << "\tw=" << m_triangles[ndx].v2.w() << ")\t" << v2Properties << TestLog::EndMessage;
1143 log << TestLog::Message << TestLog::EndMessage;
1146 ctx.clearColor (0, 0, 0, 1);
1147 ctx.clearDepthf (1.0f);
1148 ctx.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1149 ctx.viewport (m_viewport.left, m_viewport.bottom, m_viewport.width, m_viewport.height);
1150 ctx.useProgram (programId);
1151 ctx.blendFunc (GL_ONE, GL_ONE);
1152 ctx.enable (GL_BLEND);
1153 ctx.enableVertexAttribArray (positionLoc);
1154 ctx.enableVertexAttribArray (colorLoc);
1155 ctx.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat[8]), &m_triangles[0].v0);
1156 ctx.vertexAttribPointer (colorLoc, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat[8]), &m_triangles[0].c0);
1157 ctx.drawArrays (GL_TRIANGLES, 0, verticesPerTriangle * (glw::GLsizei)m_triangles.size());
1158 ctx.disableVertexAttribArray (positionLoc);
1159 ctx.disableVertexAttribArray (colorLoc);
1161 ctx.deleteProgram (programId);
1165 class QuadFillTest : public TriangleFillTest
1168 QuadFillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport, const tcu::Vec3& d1, const tcu::Vec3& d2, const tcu::Vec3& center_ = tcu::Vec3(0, 0, 0));
1171 QuadFillTest::QuadFillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport, const tcu::Vec3& d1, const tcu::Vec3& d2, const tcu::Vec3& center_)
1172 : TriangleFillTest(context, name, description, viewport)
1174 const float radius = 40000.0f;
1175 const tcu::Vec4 center = tcu::Vec4(center_.x(), center_.y(), center_.z(), 1.0f);
1176 const tcu::Vec4 halfWhite = tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
1177 const tcu::Vec4 halfRed = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.5f);
1178 const tcu::Vec4 e1 = radius * tcu::Vec4(d1.x(), d1.y(), d1.z(), 0.0f);
1179 const tcu::Vec4 e2 = radius * tcu::Vec4(d2.x(), d2.y(), d2.z(), 0.0f);
1181 FillTriangle triangle1;
1182 FillTriangle triangle2;
1184 triangle1.c0 = halfWhite;
1185 triangle1.c1 = halfWhite;
1186 triangle1.c2 = halfWhite;
1187 triangle1.v0 = center + e1 + e2;
1188 triangle1.v1 = center + e1 - e2;
1189 triangle1.v2 = center - e1 - e2;
1190 m_triangles.push_back(triangle1);
1192 triangle2.c0 = halfRed;
1193 triangle2.c1 = halfRed;
1194 triangle2.c2 = halfRed;
1195 triangle2.v0 = center + e1 + e2;
1196 triangle2.v1 = center - e1 - e2;
1197 triangle2.v2 = center - e1 + e2;
1198 m_triangles.push_back(triangle2);
1201 class TriangleFanFillTest : public TriangleFillTest
1204 TriangleFanFillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport);
1207 TriangleFanFillTest::TriangleFanFillTest (Context& context, const char* name, const char* description, const rr::WindowRectangle& viewport)
1208 : TriangleFillTest(context, name, description, viewport)
1210 const float radius = 70000.0f;
1211 const int trianglesPerVisit = 40;
1212 const tcu::Vec4 center = tcu::Vec4(0, 0, 0, 1.0f);
1213 const tcu::Vec4 halfWhite = tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
1214 const tcu::Vec4 oddSliceColor = tcu::Vec4(0.0f, 0.0f, 0.5f, 0.0f);
1216 // create a continuous surface that goes through all 6 clip planes
1230 const struct ClipPlaneVisit
1232 const tcu::Vec3 corner;
1233 const tcu::Vec3 entryPoint;
1234 const tcu::Vec3 exitPoint;
1237 { tcu::Vec3( 1, 1, 1), tcu::Vec3( 0, 1, 1), tcu::Vec3( 1, 0, 1) },
1238 { tcu::Vec3( 1,-1, 1), tcu::Vec3( 1, 0, 1), tcu::Vec3( 1,-1, 0) },
1239 { tcu::Vec3( 1,-1,-1), tcu::Vec3( 1,-1, 0), tcu::Vec3( 0,-1,-1) },
1240 { tcu::Vec3(-1,-1,-1), tcu::Vec3( 0,-1,-1), tcu::Vec3(-1, 0,-1) },
1241 { tcu::Vec3(-1, 1,-1), tcu::Vec3(-1, 0,-1), tcu::Vec3(-1, 1, 0) },
1242 { tcu::Vec3(-1, 1, 1), tcu::Vec3(-1, 1, 0), tcu::Vec3( 0, 1, 1) },
1245 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(visits); ++ndx)
1247 const ClipPlaneVisit& visit = visits[ndx];
1249 for (int tri = 0; tri < trianglesPerVisit; ++tri)
1254 if (tri == 0) // first vertex is magic
1256 vertex0 = visit.entryPoint;
1260 const tcu::Vec3 v1 = visit.entryPoint - visit.corner;
1261 const tcu::Vec3 v2 = visit.exitPoint - visit.corner;
1263 vertex0 = visit.corner + tcu::normalize(tcu::mix(v1, v2, tcu::Vec3(float(tri)/trianglesPerVisit)));
1266 if (tri == trianglesPerVisit-1) // last vertex is magic
1268 vertex1 = visit.exitPoint;
1272 const tcu::Vec3 v1 = visit.entryPoint - visit.corner;
1273 const tcu::Vec3 v2 = visit.exitPoint - visit.corner;
1275 vertex1 = visit.corner + tcu::normalize(tcu::mix(v1, v2, tcu::Vec3(float(tri+1)/trianglesPerVisit)));
1280 FillTriangle triangle;
1282 triangle.c0 = (tri % 2) ? halfWhite : halfWhite + oddSliceColor;
1283 triangle.c1 = (tri % 2) ? halfWhite : halfWhite + oddSliceColor;
1284 triangle.c2 = (tri % 2) ? halfWhite : halfWhite + oddSliceColor;
1285 triangle.v0 = center;
1286 triangle.v1 = tcu::Vec4(vertex0.x() * radius, vertex0.y() * radius, vertex0.z() * radius, 1.0f);
1287 triangle.v2 = tcu::Vec4(vertex1.x() * radius, vertex1.y() * radius, vertex1.z() * radius, 1.0f);
1289 m_triangles.push_back(triangle);
1296 class PointsTestGroup : public TestCaseGroup
1299 PointsTestGroup (Context& context);
1304 PointsTestGroup::PointsTestGroup (Context& context)
1305 : TestCaseGroup(context, "point", "Point clipping tests")
1309 void PointsTestGroup::init (void)
1311 const float littleOverViewport = 1.0f + (2.0f / (TEST_CANVAS_SIZE)); // one pixel over the viewport edge in VIEWPORT_WHOLE, half pixels over in the reduced viewport.
1313 const tcu::Vec4 viewportTestPoints[] =
1316 tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f),
1317 tcu::Vec4( 0.1f, 0.1f, 0.1f, 1.0f),
1318 tcu::Vec4(-0.1f, 0.1f, -0.1f, 1.0f),
1319 tcu::Vec4(-0.1f, -0.1f, 0.1f, 1.0f),
1320 tcu::Vec4( 0.1f, -0.1f, -0.1f, 1.0f),
1322 // in clip volume with w != 1
1323 tcu::Vec4( 2.0f, 2.0f, 2.0f, 3.0f),
1324 tcu::Vec4(-2.0f, -2.0f, 2.0f, 3.0f),
1325 tcu::Vec4( 0.5f, -0.5f, 0.5f, 0.7f),
1326 tcu::Vec4(-0.5f, 0.5f, -0.5f, 0.7f),
1329 tcu::Vec4(-2.0f, -2.0f, 0.0f, 2.2f),
1330 tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.1f),
1331 tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.1f),
1333 // not in the volume but still between near and far planes
1334 tcu::Vec4( 1.3f, 0.0f, 0.0f, 1.0f),
1335 tcu::Vec4(-1.3f, 0.0f, 0.0f, 1.0f),
1336 tcu::Vec4( 0.0f, 1.3f, 0.0f, 1.0f),
1337 tcu::Vec4( 0.0f, -1.3f, 0.0f, 1.0f),
1339 tcu::Vec4(-1.3f, -1.3f, 0.0f, 1.0f),
1340 tcu::Vec4(-1.3f, 1.3f, 0.0f, 1.0f),
1341 tcu::Vec4( 1.3f, 1.3f, 0.0f, 1.0f),
1342 tcu::Vec4( 1.3f, -1.3f, 0.0f, 1.0f),
1344 // outside the viewport, wide points have fragments in the viewport
1345 tcu::Vec4( littleOverViewport, littleOverViewport, 0.0f, 1.0f),
1346 tcu::Vec4( 0.0f, littleOverViewport, 0.0f, 1.0f),
1347 tcu::Vec4( littleOverViewport, 0.0f, 0.0f, 1.0f),
1349 const tcu::Vec4 depthTestPoints[] =
1352 tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f),
1353 tcu::Vec4( 0.1f, 0.1f, 0.1f, 1.0f),
1354 tcu::Vec4(-0.1f, 0.1f, -0.1f, 1.0f),
1355 tcu::Vec4(-0.1f, -0.1f, 0.1f, 1.0f),
1356 tcu::Vec4( 0.1f, -0.1f, -0.1f, 1.0f),
1358 // not between the near and the far planes. These should be clipped
1359 tcu::Vec4( 0.1f, 0.0f, 1.1f, 1.0f),
1360 tcu::Vec4(-0.1f, 0.0f, -1.1f, 1.0f),
1361 tcu::Vec4(-0.0f, -0.1f, 1.1f, 1.0f),
1362 tcu::Vec4( 0.0f, 0.1f, -1.1f, 1.0f)
1365 addChild(new PointCase(m_context, "point_z_clip", "point z clipping", DE_ARRAY_BEGIN(depthTestPoints), DE_ARRAY_END(depthTestPoints), 1.0f, VIEWPORT_WHOLE));
1366 addChild(new PointCase(m_context, "point_z_clip_viewport_center", "point z clipping", DE_ARRAY_BEGIN(depthTestPoints), DE_ARRAY_END(depthTestPoints), 1.0f, VIEWPORT_CENTER));
1367 addChild(new PointCase(m_context, "point_z_clip_viewport_corner", "point z clipping", DE_ARRAY_BEGIN(depthTestPoints), DE_ARRAY_END(depthTestPoints), 1.0f, VIEWPORT_CORNER));
1369 addChild(new PointCase(m_context, "point_clip_viewport_center", "point viewport clipping", DE_ARRAY_BEGIN(viewportTestPoints), DE_ARRAY_END(viewportTestPoints), 1.0f, VIEWPORT_CENTER));
1370 addChild(new PointCase(m_context, "point_clip_viewport_corner", "point viewport clipping", DE_ARRAY_BEGIN(viewportTestPoints), DE_ARRAY_END(viewportTestPoints), 1.0f, VIEWPORT_CORNER));
1372 addChild(new PointCase(m_context, "wide_point_z_clip", "point z clipping", DE_ARRAY_BEGIN(depthTestPoints), DE_ARRAY_END(depthTestPoints), 5.0f, VIEWPORT_WHOLE));
1373 addChild(new PointCase(m_context, "wide_point_z_clip_viewport_center", "point z clipping", DE_ARRAY_BEGIN(depthTestPoints), DE_ARRAY_END(depthTestPoints), 5.0f, VIEWPORT_CENTER));
1374 addChild(new PointCase(m_context, "wide_point_z_clip_viewport_corner", "point z clipping", DE_ARRAY_BEGIN(depthTestPoints), DE_ARRAY_END(depthTestPoints), 5.0f, VIEWPORT_CORNER));
1376 addChild(new PointCase(m_context, "wide_point_clip", "point viewport clipping", DE_ARRAY_BEGIN(viewportTestPoints), DE_ARRAY_END(viewportTestPoints), 5.0f, VIEWPORT_WHOLE));
1377 addChild(new PointCase(m_context, "wide_point_clip_viewport_center", "point viewport clipping", DE_ARRAY_BEGIN(viewportTestPoints), DE_ARRAY_END(viewportTestPoints), 5.0f, VIEWPORT_CENTER));
1378 addChild(new PointCase(m_context, "wide_point_clip_viewport_corner", "point viewport clipping", DE_ARRAY_BEGIN(viewportTestPoints), DE_ARRAY_END(viewportTestPoints), 5.0f, VIEWPORT_CORNER));
1381 class LinesTestGroup : public TestCaseGroup
1384 LinesTestGroup (Context& context);
1389 LinesTestGroup::LinesTestGroup (Context& context)
1390 : TestCaseGroup(context, "line", "Line clipping tests")
1394 void LinesTestGroup::init (void)
1396 const float littleOverViewport = 1.0f + (2.0f / (TEST_CANVAS_SIZE)); // one pixel over the viewport edge in VIEWPORT_WHOLE, half pixels over in the reduced viewport.
1399 const LineRenderTestCase::ColorlessLineData viewportTestLines[] =
1401 // from center to outside of viewport
1402 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 0.0f, 1.5f, 0.0f, 1.0f)},
1403 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(-1.5f, 1.0f, 0.0f, 1.0f)},
1404 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(-1.5f, 0.0f, 0.0f, 1.0f)},
1405 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 0.2f, 0.4f, 1.5f, 1.0f)},
1406 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(-2.0f, -1.0f, 0.0f, 1.0f)},
1407 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 1.0f, 0.1f, 0.0f, 0.6f)},
1409 // from outside to inside of viewport
1410 {tcu::Vec4( 1.5f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 0.8f, -0.2f, 0.0f, 1.0f)},
1411 {tcu::Vec4( 0.0f, -1.5f, 0.0f, 1.0f), tcu::Vec4( 0.9f, -0.7f, 0.0f, 1.0f)},
1413 // from outside to outside
1414 {tcu::Vec4( 0.0f, -1.3f, 0.0f, 1.0f), tcu::Vec4( 1.3f, 0.0f, 0.0f, 1.0f)},
1416 // outside the viewport, wide lines have fragments in the viewport
1417 {tcu::Vec4(-0.8f, -littleOverViewport, 0.0f, 1.0f), tcu::Vec4( 0.0f, -littleOverViewport, 0.0f, 1.0f)},
1418 {tcu::Vec4(-littleOverViewport - 1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 0.0f, -littleOverViewport - 1.0f, 0.0f, 1.0f)},
1420 const LineRenderTestCase::ColorlessLineData depthTestLines[] =
1422 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 1.3f, 1.0f, 2.0f, 1.0f)},
1423 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 1.3f, -1.0f, 2.0f, 1.0f)},
1424 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(-1.0f, -1.1f, -2.0f, 1.0f)},
1425 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(-1.0f, 1.1f, -2.0f, 1.0f)},
1426 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4( 1.0f, 0.1f, 2.0f, 0.6f)},
1428 const LineRenderTestCase::ColorlessLineData longTestLines[] =
1430 {tcu::Vec4( -41000.0f, -40000.0f, -1000000.0f, 1.0f), tcu::Vec4( 41000.0f, 40000.0f, 1000000.0f, 1.0f)},
1431 {tcu::Vec4( 41000.0f, -40000.0f, 1000000.0f, 1.0f), tcu::Vec4(-41000.0f, 40000.0f, -1000000.0f, 1.0f)},
1432 {tcu::Vec4( 0.5f, -40000.0f, 100000.0f, 1.0f), tcu::Vec4( 0.5f, 40000.0f, -100000.0f, 1.0f)},
1433 {tcu::Vec4( -0.5f, 40000.0f, 100000.0f, 1.0f), tcu::Vec4(-0.5f, -40000.0f, -100000.0f, 1.0f)},
1436 // line attribute clipping
1437 const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
1438 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1439 const tcu::Vec4 lightBlue (0.3f, 0.3f, 1.0f, 1.0f);
1440 const LineRenderTestCase::ColoredLineData colorTestLines[] =
1442 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.3f, 1.0f, 2.0f, 1.0f), yellow },
1443 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.3f, -1.0f, 2.0f, 1.0f), lightBlue },
1444 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), red, tcu::Vec4(-1.0f, -1.0f, -2.0f, 1.0f), yellow },
1445 {tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), red, tcu::Vec4(-1.0f, 1.0f, -2.0f, 1.0f), lightBlue },
1449 addChild(new LineCase(m_context, "line_z_clip", "line z clipping", DE_ARRAY_BEGIN(depthTestLines), DE_ARRAY_END(depthTestLines), 1.0f, VIEWPORT_WHOLE));
1450 addChild(new LineCase(m_context, "line_z_clip_viewport_center", "line z clipping", DE_ARRAY_BEGIN(depthTestLines), DE_ARRAY_END(depthTestLines), 1.0f, VIEWPORT_CENTER));
1451 addChild(new LineCase(m_context, "line_z_clip_viewport_corner", "line z clipping", DE_ARRAY_BEGIN(depthTestLines), DE_ARRAY_END(depthTestLines), 1.0f, VIEWPORT_CORNER));
1453 addChild(new LineCase(m_context, "line_clip_viewport_center", "line viewport clipping", DE_ARRAY_BEGIN(viewportTestLines), DE_ARRAY_END(viewportTestLines), 1.0f, VIEWPORT_CENTER));
1454 addChild(new LineCase(m_context, "line_clip_viewport_corner", "line viewport clipping", DE_ARRAY_BEGIN(viewportTestLines), DE_ARRAY_END(viewportTestLines), 1.0f, VIEWPORT_CORNER));
1456 addChild(new LineCase(m_context, "wide_line_z_clip", "line z clipping", DE_ARRAY_BEGIN(depthTestLines), DE_ARRAY_END(depthTestLines), 5.0f, VIEWPORT_WHOLE));
1457 addChild(new LineCase(m_context, "wide_line_z_clip_viewport_center", "line z clipping", DE_ARRAY_BEGIN(depthTestLines), DE_ARRAY_END(depthTestLines), 5.0f, VIEWPORT_CENTER));
1458 addChild(new LineCase(m_context, "wide_line_z_clip_viewport_corner", "line z clipping", DE_ARRAY_BEGIN(depthTestLines), DE_ARRAY_END(depthTestLines), 5.0f, VIEWPORT_CORNER));
1460 addChild(new LineCase(m_context, "wide_line_clip", "line viewport clipping", DE_ARRAY_BEGIN(viewportTestLines), DE_ARRAY_END(viewportTestLines), 5.0f, VIEWPORT_WHOLE));
1461 addChild(new LineCase(m_context, "wide_line_clip_viewport_center", "line viewport clipping", DE_ARRAY_BEGIN(viewportTestLines), DE_ARRAY_END(viewportTestLines), 5.0f, VIEWPORT_CENTER));
1462 addChild(new LineCase(m_context, "wide_line_clip_viewport_corner", "line viewport clipping", DE_ARRAY_BEGIN(viewportTestLines), DE_ARRAY_END(viewportTestLines), 5.0f, VIEWPORT_CORNER));
1464 addChild(new LineCase(m_context, "long_line_clip", "line viewport clipping", DE_ARRAY_BEGIN(longTestLines), DE_ARRAY_END(longTestLines), 1.0f, VIEWPORT_WHOLE, 2));
1465 addChild(new LineCase(m_context, "long_wide_line_clip", "line viewport clipping", DE_ARRAY_BEGIN(longTestLines), DE_ARRAY_END(longTestLines), 5.0f, VIEWPORT_WHOLE, 2));
1467 // line attribute clipping
1468 addChild(new ColoredLineCase(m_context, "line_attrib_clip", "line attribute clipping", DE_ARRAY_BEGIN(colorTestLines), DE_ARRAY_END(colorTestLines), 1.0f, VIEWPORT_WHOLE));
1469 addChild(new ColoredLineCase(m_context, "wide_line_attrib_clip", "line attribute clipping", DE_ARRAY_BEGIN(colorTestLines), DE_ARRAY_END(colorTestLines), 5.0f, VIEWPORT_WHOLE));
1472 class PolysTestGroup : public TestCaseGroup
1475 PolysTestGroup (Context& context);
1480 PolysTestGroup::PolysTestGroup (Context& context)
1481 : TestCaseGroup(context, "polygon", "Polygon clipping tests")
1485 void PolysTestGroup::init (void)
1487 const float large = 100000.0f;
1488 const float offset = 0.9f;
1489 const tcu::Vec4 white (1.0f, 1.0f, 1.0f, 1.0f);
1490 const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
1491 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1492 const tcu::Vec4 blue (0.0f, 0.0f, 1.0f, 1.0f);
1496 const TriangleCase::TriangleData viewportPolys[] =
1498 // one vertex clipped
1499 {tcu::Vec4(-0.8f, -0.2f, 0.0f, 1.0f), white, tcu::Vec4(-0.8f, 0.2f, 0.0f, 1.0f), white, tcu::Vec4(-1.3f, 0.05f, 0.0f, 1.0f), white},
1501 // two vertices clipped
1502 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), white, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), white, tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), white},
1504 // three vertices clipped
1505 {tcu::Vec4(-1.1f, 0.6f, 0.0f, 1.0f), white, tcu::Vec4(-1.1f, 1.1f, 0.0f, 1.0f), white, tcu::Vec4(-0.6f, 1.1f, 0.0f, 1.0f), white},
1506 {tcu::Vec4( 0.8f, 1.1f, 0.0f, 1.0f), white, tcu::Vec4( 0.95f,-1.1f, 0.0f, 1.0f), white, tcu::Vec4( 3.0f, 0.0f, 0.0f, 1.0f), white},
1508 const TriangleCase::TriangleData depthPolys[] =
1510 // one vertex clipped to Z+
1511 {tcu::Vec4(-0.2f, 0.7f, 0.0f, 1.0f), white, tcu::Vec4( 0.2f, 0.7f, 0.0f, 1.0f), white, tcu::Vec4( 0.0f, 0.9f, 2.0f, 1.0f), white},
1513 // two vertices clipped to Z-
1514 {tcu::Vec4( 0.9f, 0.4f, -1.5f, 1.0f), white, tcu::Vec4( 0.9f, -0.4f, -1.5f, 1.0f), white, tcu::Vec4( 0.6f, 0.0f, 0.0f, 1.0f), white},
1516 // three vertices clipped
1517 {tcu::Vec4(-0.9f, 0.6f, -2.0f, 1.0f), white, tcu::Vec4(-0.9f, -0.6f, -2.0f, 1.0f), white, tcu::Vec4(-0.4f, 0.0f, 2.0f, 1.0f), white},
1519 // three vertices clipped by X, Y and Z
1520 {tcu::Vec4( 0.0f, -1.2f, 0.0f, 1.0f), white, tcu::Vec4( 0.0f, 0.5f, -1.5f, 1.0f), white, tcu::Vec4( 1.2f, -0.9f, 0.0f, 1.0f), white},
1522 const TriangleCase::TriangleData largePolys[] =
1524 // one vertex clipped
1525 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), white, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), white, tcu::Vec4( 0.0f, -large, 2.0f, 1.0f), white},
1527 // two vertices clipped
1528 {tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), white, tcu::Vec4( large, 0.5f, 0.0f, 1.0f), white, tcu::Vec4( 0.5f, large, 0.0f, 1.0f), white},
1530 // three vertices clipped
1531 {tcu::Vec4(-0.9f, -large, 0.0f, 1.0f), white, tcu::Vec4(-1.1f, -large, 0.0f, 1.0f), white, tcu::Vec4(-0.9f, large, 0.0f, 1.0f), white},
1533 const TriangleCase::TriangleData largeDepthPolys[] =
1535 // one vertex clipped
1536 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), white, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), white, tcu::Vec4( 0.0f, -large, large, 1.0f), white},
1538 // two vertices clipped
1539 {tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), white, tcu::Vec4( 0.9f, large/2, -large, 1.0f), white, tcu::Vec4( large/4, 0.0f, -large, 1.0f), white},
1541 // three vertices clipped
1542 {tcu::Vec4(-0.9f, large/4, large, 1.0f), white, tcu::Vec4(-0.5f, -large/4, -large, 1.0f), white, tcu::Vec4(-0.2f, large/4, large, 1.0f), white},
1544 const TriangleCase::TriangleData attribPolys[] =
1546 // one vertex clipped to edge, large
1547 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -large, 2.0f, 1.0f), blue},
1549 // two vertices clipped to edges
1550 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1552 // two vertices clipped to edges, with non-uniform w
1553 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1555 // three vertices clipped, large, Z
1556 {tcu::Vec4(-0.9f, large/4, large, 1.0f), red, tcu::Vec4(-0.5f, -large/4, -large, 1.0f), yellow, tcu::Vec4(-0.2f, large/4, large, 1.0f), blue},
1559 addChild(new TriangleCase(m_context, "poly_clip_viewport_center", "polygon viewport clipping", DE_ARRAY_BEGIN(viewportPolys), DE_ARRAY_END(viewportPolys), VIEWPORT_CENTER));
1560 addChild(new TriangleCase(m_context, "poly_clip_viewport_corner", "polygon viewport clipping", DE_ARRAY_BEGIN(viewportPolys), DE_ARRAY_END(viewportPolys), VIEWPORT_CORNER));
1562 addChild(new TriangleCase(m_context, "poly_z_clip", "polygon z clipping", DE_ARRAY_BEGIN(depthPolys), DE_ARRAY_END(depthPolys), VIEWPORT_WHOLE));
1563 addChild(new TriangleCase(m_context, "poly_z_clip_viewport_center", "polygon z clipping", DE_ARRAY_BEGIN(depthPolys), DE_ARRAY_END(depthPolys), VIEWPORT_CENTER));
1564 addChild(new TriangleCase(m_context, "poly_z_clip_viewport_corner", "polygon z clipping", DE_ARRAY_BEGIN(depthPolys), DE_ARRAY_END(depthPolys), VIEWPORT_CORNER));
1566 addChild(new TriangleCase(m_context, "large_poly_clip_viewport_center", "polygon viewport clipping", DE_ARRAY_BEGIN(largePolys), DE_ARRAY_END(largePolys), VIEWPORT_CENTER));
1567 addChild(new TriangleCase(m_context, "large_poly_clip_viewport_corner", "polygon viewport clipping", DE_ARRAY_BEGIN(largePolys), DE_ARRAY_END(largePolys), VIEWPORT_CORNER));
1569 addChild(new TriangleCase(m_context, "large_poly_z_clip", "polygon z clipping", DE_ARRAY_BEGIN(largeDepthPolys), DE_ARRAY_END(largeDepthPolys), VIEWPORT_WHOLE));
1570 addChild(new TriangleCase(m_context, "large_poly_z_clip_viewport_center", "polygon z clipping", DE_ARRAY_BEGIN(largeDepthPolys), DE_ARRAY_END(largeDepthPolys), VIEWPORT_CENTER));
1571 addChild(new TriangleCase(m_context, "large_poly_z_clip_viewport_corner", "polygon z clipping", DE_ARRAY_BEGIN(largeDepthPolys), DE_ARRAY_END(largeDepthPolys), VIEWPORT_CORNER));
1573 addChild(new TriangleAttributeCase(m_context, "poly_attrib_clip", "polygon clipping", DE_ARRAY_BEGIN(attribPolys), DE_ARRAY_END(attribPolys), VIEWPORT_WHOLE));
1574 addChild(new TriangleAttributeCase(m_context, "poly_attrib_clip_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(attribPolys), DE_ARRAY_END(attribPolys), VIEWPORT_CENTER));
1575 addChild(new TriangleAttributeCase(m_context, "poly_attrib_clip_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(attribPolys), DE_ARRAY_END(attribPolys), VIEWPORT_CORNER));
1578 // multiple polygons
1581 const TriangleAttributeCase::TriangleData polys[] =
1583 // one vertex clipped to edge
1584 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, 2.0f, 1.0f), blue},
1586 // two vertices clipped to edges
1587 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1589 // two vertices clipped to edges, with non-uniform w
1590 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1591 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1592 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1593 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1595 // three vertices clipped, Z
1596 {tcu::Vec4(-0.9f, offset/4, offset, 1.0f), red, tcu::Vec4(-0.5f, -offset/4, -offset, 1.0f), yellow, tcu::Vec4(-0.2f, offset/4, offset, 1.0f), blue},
1599 addChild(new TriangleAttributeCase(m_context, "multiple_0", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1600 addChild(new TriangleAttributeCase(m_context, "multiple_0_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1601 addChild(new TriangleAttributeCase(m_context, "multiple_0_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1605 const TriangleAttributeCase::TriangleData polys[] =
1607 // one vertex clipped to z
1608 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, 2.0f, 1.0f), blue},
1610 // two vertices clipped to edges
1611 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1613 // two vertices clipped to edges, with non-uniform w
1614 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1615 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1616 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1617 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, 16.0f*tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1620 addChild(new TriangleAttributeCase(m_context, "multiple_1", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1621 addChild(new TriangleAttributeCase(m_context, "multiple_1_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1622 addChild(new TriangleAttributeCase(m_context, "multiple_1_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1626 const TriangleAttributeCase::TriangleData polys[] =
1628 // one vertex clipped to z
1629 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, 2.0f, 1.0f), blue},
1631 // two vertices clipped to edges
1632 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1634 // two vertices clipped to edges
1635 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1636 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1637 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1638 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1641 addChild(new TriangleAttributeCase(m_context, "multiple_2", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1642 addChild(new TriangleAttributeCase(m_context, "multiple_2_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1643 addChild(new TriangleAttributeCase(m_context, "multiple_2_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1647 const TriangleAttributeCase::TriangleData polys[] =
1649 // one vertex clipped to z
1650 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, -2.0f, 1.0f), blue},
1652 // two vertices clipped to edges
1653 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1654 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1655 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1656 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1659 addChild(new TriangleAttributeCase(m_context, "multiple_3", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1660 addChild(new TriangleAttributeCase(m_context, "multiple_3_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1661 addChild(new TriangleAttributeCase(m_context, "multiple_3_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1665 const TriangleAttributeCase::TriangleData polys[] =
1667 // one vertex clipped to z
1668 {tcu::Vec4(0.3f, 0.2f, 0.0f, 1.0f), red, tcu::Vec4( 0.3f, -0.2f, 0.0f, 1.0f), yellow, tcu::Vec4( offset, 0.0f, 2.0f, 1.0f), blue},
1670 // two vertices clipped to edges
1671 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1672 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1673 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1674 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1677 addChild(new TriangleAttributeCase(m_context, "multiple_4", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1678 addChild(new TriangleAttributeCase(m_context, "multiple_4_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1679 addChild(new TriangleAttributeCase(m_context, "multiple_4_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1683 const TriangleAttributeCase::TriangleData polys[] =
1685 // one vertex clipped to z
1686 {tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f), red, tcu::Vec4(-0.3f, -0.2f, 0.0f, 1.0f), yellow, tcu::Vec4(-offset, 0.0f, 2.0f, 1.0f), blue},
1688 // two vertices clipped to edges
1689 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1690 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1691 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1692 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1695 addChild(new TriangleAttributeCase(m_context, "multiple_5", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1696 addChild(new TriangleAttributeCase(m_context, "multiple_5_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1697 addChild(new TriangleAttributeCase(m_context, "multiple_5_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1701 const TriangleAttributeCase::TriangleData polys[] =
1703 // one vertex clipped to z
1704 {tcu::Vec4(-0.2f, 0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, 0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, offset, 2.0f, 1.0f), blue},
1706 // two vertices clipped to edges
1707 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1708 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1709 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1710 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1713 addChild(new TriangleAttributeCase(m_context, "multiple_6", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1714 addChild(new TriangleAttributeCase(m_context, "multiple_6_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1715 addChild(new TriangleAttributeCase(m_context, "multiple_6_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1719 const TriangleAttributeCase::TriangleData polys[] =
1721 // two vertices clipped to edges
1722 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1724 // two vertices clipped to edges
1725 {tcu::Vec4( 0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, -0.6f, 0.0f, 1.0f), blue},
1726 {tcu::Vec4( 0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4( 1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.6f, 0.6f, 0.0f, 1.0f), blue},
1727 {tcu::Vec4(-0.6f, 1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, 0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, 0.6f, 0.0f, 1.0f), blue},
1728 {tcu::Vec4(-0.6f, -1.2f, 0.0f, 1.0f), red, tcu::Vec4(-1.2f, -0.6f, 0.0f, 1.0f), yellow, tcu::Vec4(-0.6f, -0.6f, 0.0f, 1.0f), blue},
1731 addChild(new TriangleAttributeCase(m_context, "multiple_7", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1732 addChild(new TriangleAttributeCase(m_context, "multiple_7_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1733 addChild(new TriangleAttributeCase(m_context, "multiple_7_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1737 const TriangleAttributeCase::TriangleData polys[] =
1739 // one vertex clipped to z
1740 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, 2.0f, 1.0f), blue},
1743 {tcu::Vec4( -1.0f, -1.0f, 0.0f, 1.0f), white, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), white, tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), white},
1744 {tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), blue, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), blue, tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), blue},
1747 addChild(new TriangleAttributeCase(m_context, "multiple_8", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1748 addChild(new TriangleAttributeCase(m_context, "multiple_8_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1749 addChild(new TriangleAttributeCase(m_context, "multiple_8_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1753 const TriangleAttributeCase::TriangleData polys[] =
1755 // one vertex clipped to z
1756 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, 2.0f, 1.0f), blue},
1759 {tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), red},
1760 {tcu::Vec4( -1.0f, -1.0f, 0.0f, 1.0f), blue, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), blue, tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), blue},
1763 addChild(new TriangleAttributeCase(m_context, "multiple_9", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1764 addChild(new TriangleAttributeCase(m_context, "multiple_9_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1765 addChild(new TriangleAttributeCase(m_context, "multiple_9_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1769 const TriangleAttributeCase::TriangleData polys[] =
1771 // one vertex clipped to z
1772 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, 2.0f, 1.0f), blue},
1775 {tcu::Vec4( -1.0f, -1.0f, 0.0f, 1.0f), white, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), white, tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), white},
1776 {tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), red},
1777 {tcu::Vec4( -1.0f, -1.0f, 0.0f, 1.0f), blue, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), blue, tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), blue},
1780 addChild(new TriangleAttributeCase(m_context, "multiple_10", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1781 addChild(new TriangleAttributeCase(m_context, "multiple_10_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1782 addChild(new TriangleAttributeCase(m_context, "multiple_10_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1786 const TriangleAttributeCase::TriangleData polys[] =
1788 // one vertex clipped to z
1789 {tcu::Vec4(-0.2f, -0.3f, 0.0f, 1.0f), red, tcu::Vec4( 0.2f, -0.3f, 0.0f, 1.0f), yellow, tcu::Vec4( 0.0f, -offset, 2.0f, 1.0f), blue},
1792 {tcu::Vec4( -1.0f, -1.0f, 0.0f, 1.0f), white, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), white, tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), white},
1793 {tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), red, tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), red},
1794 {tcu::Vec4( -1.0f, -1.0f, 0.0f, 1.0f), blue, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), blue, tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), blue},
1795 {tcu::Vec4( -1.0f, 1.0f, 0.0f, 1.0f), yellow, tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), yellow, tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), yellow},
1798 addChild(new TriangleAttributeCase(m_context, "multiple_11", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_WHOLE));
1799 addChild(new TriangleAttributeCase(m_context, "multiple_11_viewport_center", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CENTER));
1800 addChild(new TriangleAttributeCase(m_context, "multiple_11_viewport_corner", "polygon clipping", DE_ARRAY_BEGIN(polys), DE_ARRAY_END(polys), VIEWPORT_CORNER));
1805 class PolyEdgesTestGroup : public TestCaseGroup
1808 PolyEdgesTestGroup (Context& context);
1813 PolyEdgesTestGroup::PolyEdgesTestGroup (Context& context)
1814 : TestCaseGroup(context, "polygon_edge", "Polygon clipping edge tests")
1818 void PolyEdgesTestGroup::init (void)
1823 tcu::Vec3 d1; // tangent
1824 tcu::Vec3 d2; // bi-tangent
1827 { tcu::Vec3( 1, 1, 1), tcu::Vec3( 1, -1, 1) },
1828 { tcu::Vec3( 1, 1, 1), tcu::Vec3(-1, 1.1f, 1) },
1829 { tcu::Vec3( 1, 1, 0), tcu::Vec3(-1, 1, 0) },
1830 { tcu::Vec3( 0, 1, 0), tcu::Vec3( 1, 0, 0) },
1831 { tcu::Vec3( 0, 1, 0), tcu::Vec3( 1, 0.1f, 0) },
1835 const struct EdgeQuad
1837 tcu::Vec3 d1; // tangent
1838 tcu::Vec3 d2; // bi-tangent
1839 tcu::Vec3 center; // center
1842 { tcu::Vec3( 1, 0.01f, 0 ), tcu::Vec3( 0, 0.01f, 0), tcu::Vec3( 0, 0.99f, 0 ) }, // edge near x-plane
1843 { tcu::Vec3( 0.01f, 1, 0 ), tcu::Vec3( 0.01f, 0, 0), tcu::Vec3( 0.99f, 0, 0 ) }, // edge near y-plane
1844 { tcu::Vec3( 1, 1, 0.01f), tcu::Vec3( 0.01f, -0.01f, 0), tcu::Vec3( 0, 0, 0.99f) }, // edge near z-plane
1847 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(quads); ++ndx)
1848 addChild(new QuadFillTest(m_context, (std::string("quad_at_origin_") + de::toString(ndx)).c_str(), "polygon edge clipping", VIEWPORT_CENTER, quads[ndx].d1, quads[ndx].d2));
1849 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(edgeQuads); ++ndx)
1850 addChild(new QuadFillTest(m_context, (std::string("quad_near_edge_") + de::toString(ndx)).c_str(), "polygon edge clipping", VIEWPORT_CENTER, edgeQuads[ndx].d1, edgeQuads[ndx].d2, edgeQuads[ndx].center));
1853 addChild(new TriangleFanFillTest(m_context, "poly_fan", "polygon edge clipping", VIEWPORT_CENTER));
1856 class PolyVertexClipTestGroup : public TestCaseGroup
1859 PolyVertexClipTestGroup (Context& context);
1864 PolyVertexClipTestGroup::PolyVertexClipTestGroup (Context& context)
1865 : TestCaseGroup(context, "triangle_vertex", "Clip n vertices")
1869 void PolyVertexClipTestGroup::init (void)
1871 const float far = 30000.0f;
1872 const tcu::IVec3 outside[] =
1874 // outside one clipping plane
1875 tcu::IVec3(-1, 0, 0),
1876 tcu::IVec3( 1, 0, 0),
1877 tcu::IVec3( 0, 1, 0),
1878 tcu::IVec3( 0, -1, 0),
1879 tcu::IVec3( 0, 0, 1),
1880 tcu::IVec3( 0, 0, -1),
1882 // outside two clipping planes
1883 tcu::IVec3(-1, -1, 0),
1884 tcu::IVec3( 1, -1, 0),
1885 tcu::IVec3( 1, 1, 0),
1886 tcu::IVec3(-1, 1, 0),
1888 tcu::IVec3(-1, 0, -1),
1889 tcu::IVec3( 1, 0, -1),
1890 tcu::IVec3( 1, 0, 1),
1891 tcu::IVec3(-1, 0, 1),
1893 tcu::IVec3( 0, -1, -1),
1894 tcu::IVec3( 0, 1, -1),
1895 tcu::IVec3( 0, 1, 1),
1896 tcu::IVec3( 0, -1, 1),
1898 // outside three clipping planes
1899 tcu::IVec3(-1, -1, 1),
1900 tcu::IVec3( 1, -1, 1),
1901 tcu::IVec3( 1, 1, 1),
1902 tcu::IVec3(-1, 1, 1),
1904 tcu::IVec3(-1, -1, -1),
1905 tcu::IVec3( 1, -1, -1),
1906 tcu::IVec3( 1, 1, -1),
1907 tcu::IVec3(-1, 1, -1),
1910 de::Random rnd(0xabcdef);
1912 TestCaseGroup* clipOne = new TestCaseGroup(m_context, "clip_one", "Clip one vertex");
1913 TestCaseGroup* clipTwo = new TestCaseGroup(m_context, "clip_two", "Clip two vertices");
1914 TestCaseGroup* clipThree = new TestCaseGroup(m_context, "clip_three", "Clip three vertices");
1918 addChild(clipThree);
1920 // Test 1 point clipped
1921 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(outside); ++ndx)
1923 const float w0 = rnd.getFloat(0.2f, 16.0f);
1924 const float w1 = rnd.getFloat(0.2f, 16.0f);
1925 const float w2 = rnd.getFloat(0.2f, 16.0f);
1926 const tcu::Vec4 white = tcu::Vec4( 1, 1, 1, 1);
1927 const tcu::Vec3 r0 = tcu::Vec3( 0.2f, 0.3f, 0);
1928 const tcu::Vec3 r1 = tcu::Vec3(-0.3f, -0.4f, 0);
1929 const tcu::Vec3 r2 = IVec3ToVec3(outside[ndx]) * far;
1930 const tcu::Vec4 p0 = tcu::Vec4(r0.x() * w0, r0.y() * w0, r0.z() * w0, w0);
1931 const tcu::Vec4 p1 = tcu::Vec4(r1.x() * w1, r1.y() * w1, r1.z() * w1, w1);
1932 const tcu::Vec4 p2 = tcu::Vec4(r2.x() * w2, r2.y() * w2, r2.z() * w2, w2);
1934 const std::string name = std::string("clip") +
1935 (outside[ndx].x() > 0 ? "_pos_x" : (outside[ndx].x() < 0 ? "_neg_x" : "")) +
1936 (outside[ndx].y() > 0 ? "_pos_y" : (outside[ndx].y() < 0 ? "_neg_y" : "")) +
1937 (outside[ndx].z() > 0 ? "_pos_z" : (outside[ndx].z() < 0 ? "_neg_z" : ""));
1939 const TriangleCase::TriangleData triangle = {p0, white, p1, white, p2, white};
1941 // don't try to test with degenerate (or almost degenerate) triangles
1942 if (outside[ndx].x() == 0 && outside[ndx].y() == 0)
1945 clipOne->addChild(new TriangleCase(m_context, name.c_str(), "clip one vertex", &triangle, &triangle + 1, VIEWPORT_CENTER));
1948 // Special triangles for "clip_z" cases, default triangles is not good, since it has very small visible area => problems with MSAA
1950 const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1952 const TriangleCase::TriangleData posZTriangle =
1954 tcu::Vec4( 0.0f, -0.7f, -0.9f, 1.0f), white,
1955 tcu::Vec4( 0.8f, 0.0f, -0.7f, 1.0f), white,
1956 tcu::Vec4(-0.9f, 0.9f, 3.0f, 1.0f), white
1958 const TriangleCase::TriangleData negZTriangle =
1960 tcu::Vec4( 0.0f, -0.7f, 0.9f, 1.0f), white,
1961 tcu::Vec4( 0.4f, 0.0f, 0.7f, 1.0f), white,
1962 tcu::Vec4(-0.9f, 0.9f, -3.0f, 1.0f), white
1965 clipOne->addChild(new TriangleCase(m_context, "clip_pos_z", "clip one vertex", &posZTriangle, &posZTriangle + 1, VIEWPORT_CENTER));
1966 clipOne->addChild(new TriangleCase(m_context, "clip_neg_z", "clip one vertex", &negZTriangle, &negZTriangle + 1, VIEWPORT_CENTER));
1969 // Test 2 points clipped
1970 for (int ndx1 = 0; ndx1 < DE_LENGTH_OF_ARRAY(outside); ++ndx1)
1971 for (int ndx2 = ndx1 + 1; ndx2 < DE_LENGTH_OF_ARRAY(outside); ++ndx2)
1973 const float w0 = rnd.getFloat(0.2f, 16.0f);
1974 const float w1 = rnd.getFloat(0.2f, 16.0f);
1975 const float w2 = rnd.getFloat(0.2f, 16.0f);
1976 const tcu::Vec4 white = tcu::Vec4( 1, 1, 1, 1);
1977 const tcu::Vec3 r0 = tcu::Vec3( 0.2f, 0.3f, 0);
1978 const tcu::IVec3 r1 = outside[ndx1];
1979 const tcu::IVec3 r2 = outside[ndx2];
1980 const tcu::Vec4 p0 = tcu::Vec4(r0.x() * w0, r0.y() * w0, r0.z() * w0, w0);
1981 const tcu::Vec4 p1 = tcu::Vec4(r1.x() * far * w1, r1.y() * far * w1, r1.z() * far * w1, w1);
1982 const tcu::Vec4 p2 = tcu::Vec4(r2.x() * far * w2, r2.y() * far * w2, r2.z() * far * w2, w2);
1984 const std::string name = std::string("clip") +
1985 (outside[ndx1].x() > 0 ? "_pos_x" : (outside[ndx1].x() < 0 ? "_neg_x" : "")) +
1986 (outside[ndx1].y() > 0 ? "_pos_y" : (outside[ndx1].y() < 0 ? "_neg_y" : "")) +
1987 (outside[ndx1].z() > 0 ? "_pos_z" : (outside[ndx1].z() < 0 ? "_neg_z" : "")) +
1989 (outside[ndx2].x() > 0 ? "_pos_x" : (outside[ndx2].x() < 0 ? "_neg_x" : "")) +
1990 (outside[ndx2].y() > 0 ? "_pos_y" : (outside[ndx2].y() < 0 ? "_neg_y" : "")) +
1991 (outside[ndx2].z() > 0 ? "_pos_z" : (outside[ndx2].z() < 0 ? "_neg_z" : ""));
1993 const TriangleCase::TriangleData triangle = {p0, white, p1, white, p2, white};
1995 if (twoPointClippedTriangleInvisible(r0, r1, r2))
1998 clipTwo->addChild(new TriangleCase(m_context, name.c_str(), "clip two vertices", &triangle, &triangle + 1, VIEWPORT_CENTER));
2001 // Test 3 points clipped
2002 for (int ndx1 = 0; ndx1 < DE_LENGTH_OF_ARRAY(outside); ++ndx1)
2003 for (int ndx2 = ndx1 + 1; ndx2 < DE_LENGTH_OF_ARRAY(outside); ++ndx2)
2004 for (int ndx3 = ndx2 + 1; ndx3 < DE_LENGTH_OF_ARRAY(outside); ++ndx3)
2006 const float w0 = rnd.getFloat(0.2f, 16.0f);
2007 const float w1 = rnd.getFloat(0.2f, 16.0f);
2008 const float w2 = rnd.getFloat(0.2f, 16.0f);
2009 const tcu::Vec4 white = tcu::Vec4(1, 1, 1, 1);
2010 const tcu::IVec3 r0 = outside[ndx1];
2011 const tcu::IVec3 r1 = outside[ndx2];
2012 const tcu::IVec3 r2 = outside[ndx3];
2013 const tcu::Vec4 p0 = tcu::Vec4(r0.x() * far * w0, r0.y() * far * w0, r0.z() * far * w0, w0);
2014 const tcu::Vec4 p1 = tcu::Vec4(r1.x() * far * w1, r1.y() * far * w1, r1.z() * far * w1, w1);
2015 const tcu::Vec4 p2 = tcu::Vec4(r2.x() * far * w2, r2.y() * far * w2, r2.z() * far * w2, w2);
2017 // ignore cases where polygon is along xz or yz planes
2018 if (pointsOnLine(r0.swizzle(0, 1), r1.swizzle(0, 1), r2.swizzle(0, 1)))
2021 // triangle is visible only if it intersects the origin
2022 if (pointOnTriangle(tcu::IVec3(0, 0, 0), r0, r1, r2))
2024 const TriangleCase::TriangleData triangle = {p0, white, p1, white, p2, white};
2025 const std::string name = std::string("clip") +
2026 (outside[ndx1].x() > 0 ? "_pos_x" : (outside[ndx1].x() < 0 ? "_neg_x" : "")) +
2027 (outside[ndx1].y() > 0 ? "_pos_y" : (outside[ndx1].y() < 0 ? "_neg_y" : "")) +
2028 (outside[ndx1].z() > 0 ? "_pos_z" : (outside[ndx1].z() < 0 ? "_neg_z" : "")) +
2030 (outside[ndx2].x() > 0 ? "_pos_x" : (outside[ndx2].x() < 0 ? "_neg_x" : "")) +
2031 (outside[ndx2].y() > 0 ? "_pos_y" : (outside[ndx2].y() < 0 ? "_neg_y" : "")) +
2032 (outside[ndx2].z() > 0 ? "_pos_z" : (outside[ndx2].z() < 0 ? "_neg_z" : "")) +
2034 (outside[ndx3].x() > 0 ? "_pos_x" : (outside[ndx3].x() < 0 ? "_neg_x" : "")) +
2035 (outside[ndx3].y() > 0 ? "_pos_y" : (outside[ndx3].y() < 0 ? "_neg_y" : "")) +
2036 (outside[ndx3].z() > 0 ? "_pos_z" : (outside[ndx3].z() < 0 ? "_neg_z" : ""));
2038 clipThree->addChild(new TriangleCase(m_context, name.c_str(), "clip three vertices", &triangle, &triangle + 1, VIEWPORT_CENTER));
2045 ClippingTests::ClippingTests (Context& context)
2046 : TestCaseGroup(context, "clipping", "Clipping tests")
2050 ClippingTests::~ClippingTests (void)
2054 void ClippingTests::init (void)
2056 addChild(new PointsTestGroup (m_context));
2057 addChild(new LinesTestGroup (m_context));
2058 addChild(new PolysTestGroup (m_context));
2059 addChild(new PolyEdgesTestGroup (m_context));
2060 addChild(new PolyVertexClipTestGroup(m_context));