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 Functional rasterization tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es3fRasterizationTests.hpp"
25 #include "glsRasterizationTestUtil.hpp"
26 #include "tcuSurface.hpp"
27 #include "tcuRenderTarget.hpp"
28 #include "tcuVectorUtil.hpp"
29 #include "tcuStringTemplate.hpp"
30 #include "tcuTextureUtil.hpp"
31 #include "tcuResultCollector.hpp"
32 #include "gluShaderProgram.hpp"
33 #include "gluRenderContext.hpp"
34 #include "gluPixelTransfer.hpp"
35 #include "gluStrUtil.hpp"
36 #include "gluTextureUtil.hpp"
37 #include "deStringUtil.hpp"
38 #include "deRandom.hpp"
39 #include "glwFunctions.hpp"
40 #include "glwEnums.hpp"
53 using namespace gls::RasterizationTestUtil;
55 static const char* const s_shaderVertexTemplate = "#version 300 es\n"
56 "in highp vec4 a_position;\n"
57 "in highp vec4 a_color;\n"
58 "${INTERPOLATION}out highp vec4 v_color;\n"
59 "uniform highp float u_pointSize;\n"
62 " gl_Position = a_position;\n"
63 " gl_PointSize = u_pointSize;\n"
64 " v_color = a_color;\n"
66 static const char* const s_shaderFragmentTemplate = "#version 300 es\n"
67 "layout(location = 0) out highp vec4 fragColor;\n"
68 "${INTERPOLATION}in highp vec4 v_color;\n"
71 " fragColor = v_color;\n"
73 enum InterpolationCaseFlags
75 INTERPOLATIONFLAGS_NONE = 0,
76 INTERPOLATIONFLAGS_PROJECTED = (1 << 1),
77 INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
80 enum PrimitiveWideness
82 PRIMITIVEWIDENESS_NARROW = 0,
83 PRIMITIVEWIDENESS_WIDE,
85 PRIMITIVEWIDENESS_LAST
88 static tcu::PixelFormat getInternalFormatPixelFormat (glw::GLenum internalFormat)
90 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(glu::mapGLInternalFormat(internalFormat));
91 return tcu::PixelFormat(bitDepth.x(), bitDepth.y(), bitDepth.z(), bitDepth.w());
94 class BaseRenderingCase : public TestCase
99 RENDERTARGET_DEFAULT = 0,
100 RENDERTARGET_TEXTURE_2D,
101 RENDERTARGET_RBO_SINGLESAMPLE,
102 RENDERTARGET_RBO_MULTISAMPLE,
109 DEFAULT_RENDER_SIZE = 256,
110 SAMPLE_COUNT_MAX = -2,
113 BaseRenderingCase (Context& context, const char* name, const char* desc, RenderTarget target, int numSamples, int renderSize);
114 ~BaseRenderingCase (void);
115 virtual void init (void);
119 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, glw::GLenum primitiveType);
120 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, glw::GLenum primitiveType);
122 virtual float getLineWidth (void) const;
123 virtual float getPointSize (void) const;
124 const tcu::PixelFormat& getPixelFormat (void) const;
126 const int m_renderSize;
130 const int m_numRequestedSamples;
133 const RenderTarget m_renderTarget;
134 const glw::GLenum m_fboInternalFormat;
135 const tcu::PixelFormat m_pixelFormat;
136 glu::ShaderProgram* m_shader;
138 glw::GLuint m_texture;
140 glw::GLuint m_blitDstFbo;
141 glw::GLuint m_blitDstRbo;
144 BaseRenderingCase::BaseRenderingCase (Context& context, const char* name, const char* desc, RenderTarget target, int numSamples, int renderSize)
145 : TestCase (context, name, desc)
146 , m_renderSize (renderSize)
148 , m_subpixelBits (-1)
149 , m_flatshade (false)
150 , m_numRequestedSamples (numSamples)
151 , m_renderTarget (target)
152 , m_fboInternalFormat (GL_RGBA8)
153 , m_pixelFormat ((m_renderTarget == RENDERTARGET_DEFAULT) ? (m_context.getRenderTarget().getPixelFormat()) : (getInternalFormatPixelFormat(m_fboInternalFormat)))
161 DE_ASSERT(m_renderTarget < RENDERTARGET_LAST);
162 DE_ASSERT((m_numRequestedSamples == -1) == (m_renderTarget != RENDERTARGET_RBO_MULTISAMPLE));
165 BaseRenderingCase::~BaseRenderingCase (void)
170 void BaseRenderingCase::init (void)
172 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
173 const int width = m_context.getRenderTarget().getWidth();
174 const int height = m_context.getRenderTarget().getHeight();
175 int msaaTargetSamples = -1;
179 if (m_renderTarget == RENDERTARGET_DEFAULT && (width < m_renderSize || height < m_renderSize))
180 throw tcu::NotSupportedError(std::string("Render target size must be at least ") + de::toString(m_renderSize) + "x" + de::toString(m_renderSize));
182 if (m_renderTarget == RENDERTARGET_RBO_MULTISAMPLE)
184 glw::GLint maxSampleCount = 0;
185 gl.getInternalformativ(GL_RENDERBUFFER, m_fboInternalFormat, GL_SAMPLES, 1, &maxSampleCount);
187 if (m_numRequestedSamples == SAMPLE_COUNT_MAX)
188 msaaTargetSamples = maxSampleCount;
189 else if (maxSampleCount >= m_numRequestedSamples)
190 msaaTargetSamples = m_numRequestedSamples;
192 throw tcu::NotSupportedError("Test requires " + de::toString(m_numRequestedSamples) + "x msaa rbo");
198 tcu::StringTemplate vertexSource (s_shaderVertexTemplate);
199 tcu::StringTemplate fragmentSource (s_shaderFragmentTemplate);
200 std::map<std::string, std::string> params;
202 params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");
204 m_shader = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vertexSource.specialize(params)) << glu::FragmentSource(fragmentSource.specialize(params)));
205 if (!m_shader->isOk())
206 throw tcu::TestError("could not create shader");
210 if (m_renderTarget != RENDERTARGET_DEFAULT)
214 gl.genFramebuffers(1, &m_fbo);
215 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
217 switch (m_renderTarget)
219 case RENDERTARGET_TEXTURE_2D:
221 gl.genTextures(1, &m_texture);
222 gl.bindTexture(GL_TEXTURE_2D, m_texture);
223 gl.texStorage2D(GL_TEXTURE_2D, 1, m_fboInternalFormat, m_renderSize, m_renderSize);
225 error = gl.getError();
226 if (error == GL_OUT_OF_MEMORY)
227 throw tcu::NotSupportedError("could not create target texture, got out of memory");
228 else if (error != GL_NO_ERROR)
229 throw tcu::TestError("got " + de::toString(glu::getErrorStr(error)));
231 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
235 case RENDERTARGET_RBO_SINGLESAMPLE:
236 case RENDERTARGET_RBO_MULTISAMPLE:
238 gl.genRenderbuffers(1, &m_rbo);
239 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
241 if (m_renderTarget == RENDERTARGET_RBO_SINGLESAMPLE)
242 gl.renderbufferStorage(GL_RENDERBUFFER, m_fboInternalFormat, m_renderSize, m_renderSize);
243 else if (m_renderTarget == RENDERTARGET_RBO_MULTISAMPLE)
244 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, msaaTargetSamples, m_fboInternalFormat, m_renderSize, m_renderSize);
248 error = gl.getError();
249 if (error == GL_OUT_OF_MEMORY)
250 throw tcu::NotSupportedError("could not create target texture, got out of memory");
251 else if (error != GL_NO_ERROR)
252 throw tcu::TestError("got " + de::toString(glu::getErrorStr(error)));
254 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
263 // Resolve (blitFramebuffer) target fbo for MSAA targets
264 if (m_renderTarget == RENDERTARGET_RBO_MULTISAMPLE)
268 gl.genFramebuffers(1, &m_blitDstFbo);
269 gl.bindFramebuffer(GL_FRAMEBUFFER, m_blitDstFbo);
271 gl.genRenderbuffers(1, &m_blitDstRbo);
272 gl.bindRenderbuffer(GL_RENDERBUFFER, m_blitDstRbo);
273 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, m_renderSize, m_renderSize);
275 error = gl.getError();
276 if (error == GL_OUT_OF_MEMORY)
277 throw tcu::NotSupportedError("could not create blit target, got out of memory");
278 else if (error != GL_NO_ERROR)
279 throw tcu::TestError("got " + de::toString(glu::getErrorStr(error)));
281 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_blitDstRbo);
284 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
289 if (m_renderTarget == RENDERTARGET_DEFAULT)
290 m_numSamples = m_context.getRenderTarget().getNumSamples();
291 else if (m_renderTarget == RENDERTARGET_RBO_MULTISAMPLE)
294 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
295 gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &m_numSamples);
297 GLU_EXPECT_NO_ERROR(gl.getError(), "get RENDERBUFFER_SAMPLES");
302 gl.getIntegerv(GL_SUBPIXEL_BITS, &m_subpixelBits);
304 m_testCtx.getLog() << tcu::TestLog::Message << "Sample count = " << m_numSamples << tcu::TestLog::EndMessage;
305 m_testCtx.getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
308 void BaseRenderingCase::deinit (void)
318 m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_fbo);
324 m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_rbo);
330 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texture);
336 m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_blitDstFbo);
342 m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_blitDstRbo);
347 void BaseRenderingCase::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, glw::GLenum primitiveType)
349 // default to color white
350 const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
352 drawPrimitives(result, vertexData, colorData, primitiveType);
355 void BaseRenderingCase::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& colorData, glw::GLenum primitiveType)
357 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
358 const glw::GLint positionLoc = gl.getAttribLocation(m_shader->getProgram(), "a_position");
359 const glw::GLint colorLoc = gl.getAttribLocation(m_shader->getProgram(), "a_color");
360 const glw::GLint pointSizeLoc = gl.getUniformLocation(m_shader->getProgram(), "u_pointSize");
362 gl.clearColor (0, 0, 0, 1);
363 gl.clear (GL_COLOR_BUFFER_BIT);
364 gl.viewport (0, 0, m_renderSize, m_renderSize);
365 gl.useProgram (m_shader->getProgram());
366 gl.enableVertexAttribArray (positionLoc);
367 gl.vertexAttribPointer (positionLoc, 4, GL_FLOAT, GL_FALSE, 0, &vertexData[0]);
368 gl.enableVertexAttribArray (colorLoc);
369 gl.vertexAttribPointer (colorLoc, 4, GL_FLOAT, GL_FALSE, 0, &colorData[0]);
370 gl.uniform1f (pointSizeLoc, getPointSize());
371 gl.lineWidth (getLineWidth());
372 gl.drawArrays (primitiveType, 0, (glw::GLsizei)vertexData.size());
373 gl.disableVertexAttribArray (colorLoc);
374 gl.disableVertexAttribArray (positionLoc);
377 GLU_EXPECT_NO_ERROR (gl.getError(), "draw primitives");
380 if (m_renderTarget == RENDERTARGET_RBO_MULTISAMPLE)
383 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
384 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitDstFbo);
386 gl.blitFramebuffer(0, 0, m_renderSize, m_renderSize, 0, 0, m_renderSize, m_renderSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
387 GLU_EXPECT_NO_ERROR(gl.getError(), "blit");
390 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_blitDstFbo);
392 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
393 GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels");
395 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
399 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
400 GLU_EXPECT_NO_ERROR (gl.getError(), "read pixels");
404 float BaseRenderingCase::getLineWidth (void) const
409 float BaseRenderingCase::getPointSize (void) const
414 const tcu::PixelFormat& BaseRenderingCase::getPixelFormat (void) const
416 return m_pixelFormat;
419 class BaseTriangleCase : public BaseRenderingCase
422 BaseTriangleCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType, BaseRenderingCase::RenderTarget renderTarget, int numSamples);
423 ~BaseTriangleCase (void);
424 IterateResult iterate (void);
427 virtual void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
430 const int m_iterationCount;
431 const glw::GLenum m_primitiveDrawType;
432 bool m_allIterationsPassed;
435 BaseTriangleCase::BaseTriangleCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
436 : BaseRenderingCase (context, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
438 , m_iterationCount (3)
439 , m_primitiveDrawType (primitiveDrawType)
440 , m_allIterationsPassed (true)
444 BaseTriangleCase::~BaseTriangleCase (void)
448 BaseTriangleCase::IterateResult BaseTriangleCase::iterate (void)
450 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
451 const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription);
452 tcu::Surface resultImage (m_renderSize, m_renderSize);
453 std::vector<tcu::Vec4> drawBuffer;
454 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
456 generateTriangles(m_iteration, drawBuffer, triangles);
459 drawPrimitives(resultImage, drawBuffer, m_primitiveDrawType);
464 RasterizationArguments args;
465 TriangleSceneSpec scene;
467 args.numSamples = m_numSamples;
468 args.subpixelBits = m_subpixelBits;
469 args.redBits = getPixelFormat().redBits;
470 args.greenBits = getPixelFormat().greenBits;
471 args.blueBits = getPixelFormat().blueBits;
473 scene.triangles.swap(triangles);
475 compareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_testCtx.getLog());
478 m_allIterationsPassed = false;
482 if (++m_iteration == m_iterationCount)
484 if (m_allIterationsPassed)
485 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
487 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization");
495 class BaseLineCase : public BaseRenderingCase
498 BaseLineCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples);
499 ~BaseLineCase (void);
502 IterateResult iterate (void);
503 float getLineWidth (void) const;
506 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
509 const int m_iterationCount;
510 const glw::GLenum m_primitiveDrawType;
511 const PrimitiveWideness m_primitiveWideness;
512 bool m_allIterationsPassed;
513 bool m_multisampleRelaxationRequired;
514 float m_maxLineWidth;
515 std::vector<float> m_lineWidths;
518 BaseLineCase::BaseLineCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
519 : BaseRenderingCase (context, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
521 , m_iterationCount (3)
522 , m_primitiveDrawType (primitiveDrawType)
523 , m_primitiveWideness (wideness)
524 , m_allIterationsPassed (true)
525 , m_multisampleRelaxationRequired (false)
526 , m_maxLineWidth (1.0f)
528 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
531 BaseLineCase::~BaseLineCase (void)
535 void BaseLineCase::init (void)
537 // create line widths
538 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
540 m_lineWidths.resize(m_iterationCount, 1.0f);
542 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
544 float range[2] = { 0.0f, 0.0f };
545 m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
547 m_testCtx.getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
549 // no wide line support
550 if (range[1] <= 1.0f)
551 throw tcu::NotSupportedError("wide line support required");
553 // set hand picked sizes
554 m_lineWidths.push_back(5.0f);
555 m_lineWidths.push_back(10.0f);
556 m_lineWidths.push_back(range[1]);
557 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
559 m_maxLineWidth = range[1];
565 BaseRenderingCase::init();
568 BaseLineCase::IterateResult BaseLineCase::iterate (void)
570 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
571 const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription);
572 const float lineWidth = getLineWidth();
573 tcu::Surface resultImage (m_renderSize, m_renderSize);
574 std::vector<tcu::Vec4> drawBuffer;
575 std::vector<LineSceneSpec::SceneLine> lines;
578 if (lineWidth <= m_maxLineWidth)
581 generateLines(m_iteration, drawBuffer, lines);
584 drawPrimitives(resultImage, drawBuffer, m_primitiveDrawType);
589 RasterizationArguments args;
592 args.numSamples = m_numSamples;
593 args.subpixelBits = m_subpixelBits;
594 args.redBits = getPixelFormat().redBits;
595 args.greenBits = getPixelFormat().greenBits;
596 args.blueBits = getPixelFormat().blueBits;
598 scene.lines.swap(lines);
599 scene.lineWidth = lineWidth;
601 compareOk = verifyLineGroupRasterization(resultImage, scene, args, m_testCtx.getLog());
603 // multisampled wide lines might not be supported
604 if (scene.lineWidth != 1.0f && m_numSamples > 1 && !compareOk)
606 m_multisampleRelaxationRequired = true;
611 m_allIterationsPassed = false;
615 m_testCtx.getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
618 if (++m_iteration == m_iterationCount)
620 if (m_allIterationsPassed && m_multisampleRelaxationRequired)
621 m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Rasterization of multisampled wide lines failed");
622 else if (m_allIterationsPassed)
623 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
625 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization");
633 float BaseLineCase::getLineWidth (void) const
635 return m_lineWidths[m_iteration];
638 class PointCase : public BaseRenderingCase
641 PointCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
645 IterateResult iterate (void);
648 float getPointSize (void) const;
651 void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
654 const int m_iterationCount;
655 const PrimitiveWideness m_primitiveWideness;
656 bool m_allIterationsPassed;
658 float m_maxPointSize;
659 std::vector<float> m_pointSizes;
662 PointCase::PointCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
663 : BaseRenderingCase (context, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
665 , m_iterationCount (3)
666 , m_primitiveWideness (wideness)
667 , m_allIterationsPassed (true)
668 , m_maxPointSize (1.0f)
672 PointCase::~PointCase (void)
676 void PointCase::init (void)
678 // create point sizes
679 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
681 m_pointSizes.resize(m_iterationCount, 1.0f);
683 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
685 float range[2] = { 0.0f, 0.0f };
686 m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, range);
688 m_testCtx.getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
690 // no wide line support
691 if (range[1] <= 1.0f)
692 throw tcu::NotSupportedError("wide point support required");
694 // set hand picked sizes
695 m_pointSizes.push_back(10.0f);
696 m_pointSizes.push_back(25.0f);
697 m_pointSizes.push_back(range[1]);
698 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
700 m_maxPointSize = range[1];
706 BaseRenderingCase::init();
709 PointCase::IterateResult PointCase::iterate (void)
711 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
712 const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription);
713 const float pointSize = getPointSize();
714 tcu::Surface resultImage (m_renderSize, m_renderSize);
715 std::vector<tcu::Vec4> drawBuffer;
716 std::vector<PointSceneSpec::ScenePoint> points;
719 if (pointSize <= m_maxPointSize)
722 generatePoints(m_iteration, drawBuffer, points);
725 drawPrimitives(resultImage, drawBuffer, GL_POINTS);
730 RasterizationArguments args;
731 PointSceneSpec scene;
733 args.numSamples = m_numSamples;
734 args.subpixelBits = m_subpixelBits;
735 args.redBits = getPixelFormat().redBits;
736 args.greenBits = getPixelFormat().greenBits;
737 args.blueBits = getPixelFormat().blueBits;
739 scene.points.swap(points);
741 compareOk = verifyPointGroupRasterization(resultImage, scene, args, m_testCtx.getLog());
744 m_allIterationsPassed = false;
748 m_testCtx.getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
751 if (++m_iteration == m_iterationCount)
753 if (m_allIterationsPassed)
754 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
756 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization");
764 float PointCase::getPointSize (void) const
766 return m_pointSizes[m_iteration];
769 void PointCase::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
776 // \note: these values are chosen arbitrarily
777 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
778 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
779 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
780 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
781 outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
782 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
786 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
787 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
788 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
789 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
790 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
791 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
795 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
796 outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f);
797 outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
798 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
799 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
800 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
804 outPoints.resize(outData.size());
805 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
807 outPoints[pointNdx].position = outData[pointNdx];
808 outPoints[pointNdx].pointSize = getPointSize();
812 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
813 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
814 m_testCtx.getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
817 class TrianglesCase : public BaseTriangleCase
820 TrianglesCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
821 ~TrianglesCase (void);
823 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
826 TrianglesCase::TrianglesCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
827 : BaseTriangleCase(context, name, desc, GL_TRIANGLES, renderTarget, numSamples)
831 TrianglesCase::~TrianglesCase (void)
836 void TrianglesCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
843 // \note: these values are chosen arbitrarily
844 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
845 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
846 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
847 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
848 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
849 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
853 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
854 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
855 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
856 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
857 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
858 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
862 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
863 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
864 outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
865 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
866 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
867 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
871 outTriangles.resize(2);
872 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
873 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
874 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
876 outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false;
877 outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false;
878 outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false;
881 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
882 for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
885 << tcu::TestLog::Message
886 << "Triangle " << (triangleNdx+1) << ":"
887 << "\n\t" << outTriangles[triangleNdx].positions[0]
888 << "\n\t" << outTriangles[triangleNdx].positions[1]
889 << "\n\t" << outTriangles[triangleNdx].positions[2]
890 << tcu::TestLog::EndMessage;
894 class TriangleStripCase : public BaseTriangleCase
897 TriangleStripCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
899 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
902 TriangleStripCase::TriangleStripCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
903 : BaseTriangleCase(context, name, desc, GL_TRIANGLE_STRIP, renderTarget, numSamples)
907 void TriangleStripCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
914 // \note: these values are chosen arbitrarily
915 outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f);
916 outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f);
917 outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f);
918 outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f);
919 outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f);
923 outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f);
924 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
925 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
926 outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f);
927 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
931 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
932 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
933 outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f);
934 outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f);
935 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
939 outTriangles.resize(3);
940 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
941 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true;
942 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
944 outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true;
945 outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false;
946 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
948 outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true;
949 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
950 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
953 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
954 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
957 << tcu::TestLog::Message
958 << "\t" << outData[vtxNdx]
959 << tcu::TestLog::EndMessage;
963 class TriangleFanCase : public BaseTriangleCase
966 TriangleFanCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
968 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
971 TriangleFanCase::TriangleFanCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
972 : BaseTriangleCase(context, name, desc, GL_TRIANGLE_FAN, renderTarget, numSamples)
976 void TriangleFanCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
983 // \note: these values are chosen arbitrarily
984 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
985 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
986 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
987 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
988 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
992 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
993 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
994 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
995 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
996 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1000 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1001 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1002 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1003 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1004 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1008 outTriangles.resize(3);
1009 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1010 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1011 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true;
1013 outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true;
1014 outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false;
1015 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1017 outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true;
1018 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1019 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1022 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1023 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1026 << tcu::TestLog::Message
1027 << "\t" << outData[vtxNdx]
1028 << tcu::TestLog::EndMessage;
1032 class LinesCase : public BaseLineCase
1035 LinesCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1037 void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1040 LinesCase::LinesCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
1041 : BaseLineCase(context, name, desc, GL_LINES, wideness, renderTarget, numSamples)
1045 void LinesCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1052 // \note: these values are chosen arbitrarily
1053 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1054 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1055 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1056 outData[3] = tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f);
1057 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1058 outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
1062 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1063 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1064 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1065 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1066 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1067 outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
1071 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1072 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1073 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1074 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1075 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1076 outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
1081 outLines[0].positions[0] = outData[0];
1082 outLines[0].positions[1] = outData[1];
1083 outLines[1].positions[0] = outData[2];
1084 outLines[1].positions[1] = outData[3];
1085 outLines[2].positions[0] = outData[4];
1086 outLines[2].positions[1] = outData[5];
1089 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
1090 for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
1093 << tcu::TestLog::Message
1094 << "Line " << (lineNdx+1) << ":"
1095 << "\n\t" << outLines[lineNdx].positions[0]
1096 << "\n\t" << outLines[lineNdx].positions[1]
1097 << tcu::TestLog::EndMessage;
1101 class LineStripCase : public BaseLineCase
1104 LineStripCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1106 void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1109 LineStripCase::LineStripCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
1110 : BaseLineCase(context, name, desc, GL_LINE_STRIP, wideness, renderTarget, numSamples)
1114 void LineStripCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1121 // \note: these values are chosen arbitrarily
1122 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1123 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1124 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1125 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1129 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1130 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1131 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1132 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1136 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1137 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1138 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1139 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1144 outLines[0].positions[0] = outData[0];
1145 outLines[0].positions[1] = outData[1];
1146 outLines[1].positions[0] = outData[1];
1147 outLines[1].positions[1] = outData[2];
1148 outLines[2].positions[0] = outData[2];
1149 outLines[2].positions[1] = outData[3];
1152 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1153 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1156 << tcu::TestLog::Message
1157 << "\t" << outData[vtxNdx]
1158 << tcu::TestLog::EndMessage;
1162 class LineLoopCase : public BaseLineCase
1165 LineLoopCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1167 void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1170 LineLoopCase::LineLoopCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
1171 : BaseLineCase(context, name, desc, GL_LINE_LOOP, wideness, renderTarget, numSamples)
1175 void LineLoopCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1182 // \note: these values are chosen arbitrarily
1183 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1184 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1185 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1186 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1190 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1191 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1192 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1193 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1197 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1198 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1199 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1200 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1205 outLines[0].positions[0] = outData[0];
1206 outLines[0].positions[1] = outData[1];
1207 outLines[1].positions[0] = outData[1];
1208 outLines[1].positions[1] = outData[2];
1209 outLines[2].positions[0] = outData[2];
1210 outLines[2].positions[1] = outData[3];
1211 outLines[3].positions[0] = outData[3];
1212 outLines[3].positions[1] = outData[0];
1215 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering line loop, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1216 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1219 << tcu::TestLog::Message
1220 << "\t" << outData[vtxNdx]
1221 << tcu::TestLog::EndMessage;
1225 class FillRuleCase : public BaseRenderingCase
1228 enum FillRuleCaseType
1230 FILLRULECASE_BASIC = 0,
1231 FILLRULECASE_REVERSED,
1232 FILLRULECASE_CLIPPED_FULL,
1233 FILLRULECASE_CLIPPED_PARTIAL,
1234 FILLRULECASE_PROJECTED,
1239 FillRuleCase (Context& ctx, const char* name, const char* desc, FillRuleCaseType type, RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1240 ~FillRuleCase (void);
1241 IterateResult iterate (void);
1244 int getRenderSize (FillRuleCase::FillRuleCaseType type) const;
1245 int getNumIterations (FillRuleCase::FillRuleCaseType type) const;
1246 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const;
1248 const FillRuleCaseType m_caseType;
1250 const int m_iterationCount;
1251 bool m_allIterationsPassed;
1255 FillRuleCase::FillRuleCase (Context& ctx, const char* name, const char* desc, FillRuleCaseType type, RenderTarget renderTarget, int numSamples)
1256 : BaseRenderingCase (ctx, name, desc, renderTarget, numSamples, getRenderSize(type))
1259 , m_iterationCount (getNumIterations(type))
1260 , m_allIterationsPassed (true)
1262 DE_ASSERT(type < FILLRULECASE_LAST);
1265 FillRuleCase::~FillRuleCase (void)
1270 FillRuleCase::IterateResult FillRuleCase::iterate (void)
1272 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1273 const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription);
1274 const int thresholdRed = 1 << (8 - getPixelFormat().redBits);
1275 const int thresholdGreen = 1 << (8 - getPixelFormat().greenBits);
1276 const int thresholdBlue = 1 << (8 - getPixelFormat().blueBits);
1277 tcu::Surface resultImage (m_renderSize, m_renderSize);
1278 std::vector<tcu::Vec4> drawBuffer;
1279 bool imageShown = false;
1281 generateTriangles(m_iteration, drawBuffer);
1285 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1286 const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
1288 m_testCtx.getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
1290 gl.enable(GL_BLEND);
1291 gl.blendEquation(GL_FUNC_ADD);
1292 gl.blendFunc(GL_ONE, GL_ONE);
1293 drawPrimitives(resultImage, drawBuffer, colorBuffer, GL_TRIANGLES);
1296 // verify no overdraw
1298 const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255);
1299 bool overdraw = false;
1301 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
1303 for (int y = 0; y < resultImage.getHeight(); ++y)
1304 for (int x = 0; x < resultImage.getWidth(); ++x)
1306 const tcu::RGBA color = resultImage.getPixel(x, y);
1308 // color values are greater than triangle color? Allow lower values for multisampled edges and background.
1309 if ((color.getRed() - triangleColor.getRed()) > thresholdRed ||
1310 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
1311 (color.getBlue() - triangleColor.getBlue()) > thresholdBlue)
1317 m_testCtx.getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
1320 m_testCtx.getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1321 m_testCtx.getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1322 << tcu::TestLog::Image("Result", "Result", resultImage)
1323 << tcu::TestLog::EndImageSet;
1326 m_allIterationsPassed = false;
1330 // verify no missing fragments in the full viewport case
1331 if (m_caseType == FILLRULECASE_CLIPPED_FULL)
1333 bool missingFragments = false;
1335 m_testCtx.getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
1337 for (int y = 0; y < resultImage.getHeight(); ++y)
1338 for (int x = 0; x < resultImage.getWidth(); ++x)
1340 const tcu::RGBA color = resultImage.getPixel(x, y);
1342 // black? (background)
1343 if (color.getRed() <= thresholdRed ||
1344 color.getGreen() <= thresholdGreen ||
1345 color.getBlue() <= thresholdBlue)
1346 missingFragments = true;
1350 if (!missingFragments)
1351 m_testCtx.getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
1354 m_testCtx.getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1358 m_testCtx.getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1359 << tcu::TestLog::Image("Result", "Result", resultImage)
1360 << tcu::TestLog::EndImageSet;
1363 m_allIterationsPassed = false;
1368 if (++m_iteration == m_iterationCount)
1370 if (m_allIterationsPassed)
1371 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1373 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Found invalid pixels");
1381 int FillRuleCase::getRenderSize (FillRuleCase::FillRuleCaseType type) const
1383 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1384 return DEFAULT_RENDER_SIZE / 4;
1386 return DEFAULT_RENDER_SIZE;
1389 int FillRuleCase::getNumIterations (FillRuleCase::FillRuleCaseType type) const
1391 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1397 void FillRuleCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
1401 case FILLRULECASE_BASIC:
1402 case FILLRULECASE_REVERSED:
1403 case FILLRULECASE_PROJECTED:
1405 const int numRows = 4;
1406 const int numColumns = 4;
1407 const float quadSide = 0.15f;
1408 de::Random rnd (0xabcd);
1410 outData.resize(6 * numRows * numColumns);
1412 for (int col = 0; col < numColumns; ++col)
1413 for (int row = 0; row < numRows; ++row)
1415 const tcu::Vec2 center = tcu::Vec2((row + 0.5f) / numRows * 2.0f - 1.0f, (col + 0.5f) / numColumns * 2.0f - 1.0f);
1416 const float rotation = (iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
1417 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1418 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1419 const tcu::Vec2 quad[4] =
1421 center + sideH + sideV,
1422 center + sideH - sideV,
1423 center - sideH - sideV,
1424 center - sideH + sideV,
1427 if (m_caseType == FILLRULECASE_BASIC)
1429 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1430 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1431 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1432 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1433 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1434 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1436 else if (m_caseType == FILLRULECASE_REVERSED)
1438 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1439 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1440 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1441 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1442 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1443 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1445 else if (m_caseType == FILLRULECASE_PROJECTED)
1447 const float w0 = rnd.getFloat(0.1f, 4.0f);
1448 const float w1 = rnd.getFloat(0.1f, 4.0f);
1449 const float w2 = rnd.getFloat(0.1f, 4.0f);
1450 const float w3 = rnd.getFloat(0.1f, 4.0f);
1452 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1453 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
1454 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1455 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1456 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1457 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
1460 DE_ASSERT(DE_FALSE);
1466 case FILLRULECASE_CLIPPED_PARTIAL:
1467 case FILLRULECASE_CLIPPED_FULL:
1469 const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
1470 const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
1471 const float rotation = (iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
1472 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1473 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1474 const tcu::Vec2 quad[4] =
1476 center + sideH + sideV,
1477 center + sideH - sideV,
1478 center - sideH - sideV,
1479 center - sideH + sideV,
1483 outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1484 outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1485 outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1486 outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1487 outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1488 outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1493 DE_ASSERT(DE_FALSE);
1497 class CullingTest : public BaseRenderingCase
1500 CullingTest (Context& ctx, const char* name, const char* desc, glw::GLenum cullMode, glw::GLenum primitive, glw::GLenum faceOrder);
1501 ~CullingTest (void);
1502 IterateResult iterate (void);
1505 void generateVertices (std::vector<tcu::Vec4>& outData) const;
1506 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
1507 bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
1509 const glw::GLenum m_cullMode;
1510 const glw::GLenum m_primitive;
1511 const glw::GLenum m_faceOrder;
1514 CullingTest::CullingTest (Context& ctx, const char* name, const char* desc, glw::GLenum cullMode, glw::GLenum primitive, glw::GLenum faceOrder)
1515 : BaseRenderingCase (ctx, name, desc, RENDERTARGET_DEFAULT, -1, DEFAULT_RENDER_SIZE)
1516 , m_cullMode (cullMode)
1517 , m_primitive (primitive)
1518 , m_faceOrder (faceOrder)
1522 CullingTest::~CullingTest (void)
1526 CullingTest::IterateResult CullingTest::iterate (void)
1528 tcu::Surface resultImage(m_renderSize, m_renderSize);
1529 std::vector<tcu::Vec4> drawBuffer;
1530 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1533 generateVertices(drawBuffer);
1534 extractTriangles(triangles, drawBuffer);
1538 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1540 gl.enable(GL_CULL_FACE);
1541 gl.cullFace(m_cullMode);
1542 gl.frontFace(m_faceOrder);
1544 m_testCtx.getLog() << tcu::TestLog::Message << "Setting front face to " << glu::getWindingName(m_faceOrder) << tcu::TestLog::EndMessage;
1545 m_testCtx.getLog() << tcu::TestLog::Message << "Setting cull face to " << glu::getFaceName(m_cullMode) << tcu::TestLog::EndMessage;
1546 m_testCtx.getLog() << tcu::TestLog::Message << "Drawing test pattern (" << glu::getPrimitiveTypeName(m_primitive) << ")" << tcu::TestLog::EndMessage;
1548 drawPrimitives(resultImage, drawBuffer, m_primitive);
1553 RasterizationArguments args;
1554 TriangleSceneSpec scene;
1556 args.numSamples = m_numSamples;
1557 args.subpixelBits = m_subpixelBits;
1558 args.redBits = getPixelFormat().redBits;
1559 args.greenBits = getPixelFormat().greenBits;
1560 args.blueBits = getPixelFormat().blueBits;
1562 scene.triangles.swap(triangles);
1564 if (verifyTriangleGroupRasterization(resultImage, scene, args, m_testCtx.getLog(), VERIFICATIONMODE_WEAK))
1565 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1567 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rendering");
1573 void CullingTest::generateVertices (std::vector<tcu::Vec4>& outData) const
1575 de::Random rnd(543210);
1578 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1580 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
1581 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
1582 outData[vtxNdx].z() = 0.0f;
1583 outData[vtxNdx].w() = 1.0f;
1587 void CullingTest::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
1589 const bool cullDirection = (m_cullMode == GL_FRONT) ^ (m_faceOrder == GL_CCW);
1592 if (m_cullMode == GL_FRONT_AND_BACK)
1595 switch (m_primitive)
1599 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
1601 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
1602 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
1603 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
1605 if (triangleOrder(v0, v1, v2) != cullDirection)
1607 TriangleSceneSpec::SceneTriangle tri;
1608 tri.positions[0] = v0; tri.sharedEdge[0] = false;
1609 tri.positions[1] = v1; tri.sharedEdge[1] = false;
1610 tri.positions[2] = v2; tri.sharedEdge[2] = false;
1612 outTriangles.push_back(tri);
1618 case GL_TRIANGLE_STRIP:
1620 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
1622 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
1623 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
1624 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
1626 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
1628 TriangleSceneSpec::SceneTriangle tri;
1629 tri.positions[0] = v0; tri.sharedEdge[0] = false;
1630 tri.positions[1] = v1; tri.sharedEdge[1] = false;
1631 tri.positions[2] = v2; tri.sharedEdge[2] = false;
1633 outTriangles.push_back(tri);
1639 case GL_TRIANGLE_FAN:
1641 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
1643 const tcu::Vec4& v0 = vertices[0];
1644 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
1645 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
1647 if (triangleOrder(v0, v1, v2) != cullDirection)
1649 TriangleSceneSpec::SceneTriangle tri;
1650 tri.positions[0] = v0; tri.sharedEdge[0] = false;
1651 tri.positions[1] = v1; tri.sharedEdge[1] = false;
1652 tri.positions[2] = v2; tri.sharedEdge[2] = false;
1654 outTriangles.push_back(tri);
1665 bool CullingTest::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
1667 const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
1668 const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
1669 const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
1672 return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) < 0;
1675 class TriangleInterpolationTest : public BaseRenderingCase
1678 TriangleInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1679 ~TriangleInterpolationTest (void);
1680 IterateResult iterate (void);
1683 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
1684 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
1686 const glw::GLenum m_primitive;
1687 const bool m_projective;
1688 const int m_iterationCount;
1691 bool m_allIterationsPassed;
1694 TriangleInterpolationTest::TriangleInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, RenderTarget renderTarget, int numSamples)
1695 : BaseRenderingCase (ctx, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
1696 , m_primitive (primitive)
1697 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
1698 , m_iterationCount (3)
1700 , m_allIterationsPassed (true)
1702 m_flatshade = ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0);
1705 TriangleInterpolationTest::~TriangleInterpolationTest (void)
1710 TriangleInterpolationTest::IterateResult TriangleInterpolationTest::iterate (void)
1712 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1713 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
1714 tcu::Surface resultImage (m_renderSize, m_renderSize);
1715 std::vector<tcu::Vec4> drawBuffer;
1716 std::vector<tcu::Vec4> colorBuffer;
1717 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1720 generateVertices(m_iteration, drawBuffer, colorBuffer);
1721 extractTriangles(triangles, drawBuffer, colorBuffer);
1725 m_testCtx.getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
1726 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
1727 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
1731 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitive);
1735 RasterizationArguments args;
1736 TriangleSceneSpec scene;
1738 args.numSamples = m_numSamples;
1739 args.subpixelBits = m_subpixelBits;
1740 args.redBits = getPixelFormat().redBits;
1741 args.greenBits = getPixelFormat().greenBits;
1742 args.blueBits = getPixelFormat().blueBits;
1744 scene.triangles.swap(triangles);
1746 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_testCtx.getLog()))
1747 m_allIterationsPassed = false;
1751 if (++m_iteration == m_iterationCount)
1753 if (m_allIterationsPassed)
1754 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1756 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Found invalid pixel values");
1764 void TriangleInterpolationTest::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
1766 // use only red, green and blue
1767 const tcu::Vec4 colors[] =
1769 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
1770 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
1771 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
1774 de::Random rnd(123 + iteration * 1000 + (int)m_primitive);
1776 outVertices.resize(6);
1777 outColors.resize(6);
1779 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
1781 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
1782 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
1783 outVertices[vtxNdx].z() = 0.0f;
1786 outVertices[vtxNdx].w() = 1.0f;
1789 const float w = rnd.getFloat(0.2f, 4.0f);
1791 outVertices[vtxNdx].x() *= w;
1792 outVertices[vtxNdx].y() *= w;
1793 outVertices[vtxNdx].z() *= w;
1794 outVertices[vtxNdx].w() = w;
1797 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
1801 void TriangleInterpolationTest::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
1803 switch (m_primitive)
1807 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
1809 TriangleSceneSpec::SceneTriangle tri;
1810 tri.positions[0] = vertices[vtxNdx + 0];
1811 tri.positions[1] = vertices[vtxNdx + 1];
1812 tri.positions[2] = vertices[vtxNdx + 2];
1813 tri.sharedEdge[0] = false;
1814 tri.sharedEdge[1] = false;
1815 tri.sharedEdge[2] = false;
1819 tri.colors[0] = colors[vtxNdx + 2];
1820 tri.colors[1] = colors[vtxNdx + 2];
1821 tri.colors[2] = colors[vtxNdx + 2];
1825 tri.colors[0] = colors[vtxNdx + 0];
1826 tri.colors[1] = colors[vtxNdx + 1];
1827 tri.colors[2] = colors[vtxNdx + 2];
1830 outTriangles.push_back(tri);
1835 case GL_TRIANGLE_STRIP:
1837 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
1839 TriangleSceneSpec::SceneTriangle tri;
1840 tri.positions[0] = vertices[vtxNdx + 0];
1841 tri.positions[1] = vertices[vtxNdx + 1];
1842 tri.positions[2] = vertices[vtxNdx + 2];
1843 tri.sharedEdge[0] = false;
1844 tri.sharedEdge[1] = false;
1845 tri.sharedEdge[2] = false;
1849 tri.colors[0] = colors[vtxNdx + 2];
1850 tri.colors[1] = colors[vtxNdx + 2];
1851 tri.colors[2] = colors[vtxNdx + 2];
1855 tri.colors[0] = colors[vtxNdx + 0];
1856 tri.colors[1] = colors[vtxNdx + 1];
1857 tri.colors[2] = colors[vtxNdx + 2];
1860 outTriangles.push_back(tri);
1865 case GL_TRIANGLE_FAN:
1867 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
1869 TriangleSceneSpec::SceneTriangle tri;
1870 tri.positions[0] = vertices[0];
1871 tri.positions[1] = vertices[vtxNdx + 0];
1872 tri.positions[2] = vertices[vtxNdx + 1];
1873 tri.sharedEdge[0] = false;
1874 tri.sharedEdge[1] = false;
1875 tri.sharedEdge[2] = false;
1879 tri.colors[0] = colors[vtxNdx + 1];
1880 tri.colors[1] = colors[vtxNdx + 1];
1881 tri.colors[2] = colors[vtxNdx + 1];
1885 tri.colors[0] = colors[0];
1886 tri.colors[1] = colors[vtxNdx + 0];
1887 tri.colors[2] = colors[vtxNdx + 1];
1890 outTriangles.push_back(tri);
1900 class LineInterpolationTest : public BaseRenderingCase
1903 LineInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, PrimitiveWideness wideness, RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1904 ~LineInterpolationTest (void);
1907 IterateResult iterate (void);
1910 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
1911 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
1912 float getLineWidth (void) const;
1914 const glw::GLenum m_primitive;
1915 const bool m_projective;
1916 const int m_iterationCount;
1917 const PrimitiveWideness m_primitiveWideness;
1920 tcu::ResultCollector m_result;
1921 float m_maxLineWidth;
1922 std::vector<float> m_lineWidths;
1925 LineInterpolationTest::LineInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, PrimitiveWideness wideness, RenderTarget renderTarget, int numSamples)
1926 : BaseRenderingCase (ctx, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
1927 , m_primitive (primitive)
1928 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
1929 , m_iterationCount (3)
1930 , m_primitiveWideness (wideness)
1932 , m_maxLineWidth (1.0f)
1934 m_flatshade = ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0);
1937 LineInterpolationTest::~LineInterpolationTest (void)
1942 void LineInterpolationTest::init (void)
1944 // create line widths
1945 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1947 m_lineWidths.resize(m_iterationCount, 1.0f);
1949 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1951 float range[2] = { 0.0f, 0.0f };
1952 m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
1954 m_testCtx.getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1956 // no wide line support
1957 if (range[1] <= 1.0f)
1958 throw tcu::NotSupportedError("wide line support required");
1960 // set hand picked sizes
1961 m_lineWidths.push_back(5.0f);
1962 m_lineWidths.push_back(10.0f);
1963 m_lineWidths.push_back(range[1]);
1964 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1966 m_maxLineWidth = range[1];
1972 BaseRenderingCase::init();
1975 LineInterpolationTest::IterateResult LineInterpolationTest::iterate (void)
1977 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1978 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
1979 const float lineWidth = getLineWidth();
1980 tcu::Surface resultImage (m_renderSize, m_renderSize);
1981 std::vector<tcu::Vec4> drawBuffer;
1982 std::vector<tcu::Vec4> colorBuffer;
1983 std::vector<LineSceneSpec::SceneLine> lines;
1986 if (lineWidth <= m_maxLineWidth)
1989 generateVertices(m_iteration, drawBuffer, colorBuffer);
1990 extractLines(lines, drawBuffer, colorBuffer);
1994 m_testCtx.getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
1995 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
1996 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2000 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitive);
2004 RasterizationArguments args;
2005 LineSceneSpec scene;
2006 LineInterpolationMethod iterationResult;
2008 args.numSamples = m_numSamples;
2009 args.subpixelBits = m_subpixelBits;
2010 args.redBits = getPixelFormat().redBits;
2011 args.greenBits = getPixelFormat().greenBits;
2012 args.blueBits = getPixelFormat().blueBits;
2014 scene.lines.swap(lines);
2015 scene.lineWidth = getLineWidth();
2017 iterationResult = verifyLineGroupInterpolation(resultImage, scene, args, m_testCtx.getLog());
2018 switch (iterationResult)
2020 case LINEINTERPOLATION_STRICTLY_CORRECT:
2021 // line interpolation matches the specification
2022 m_result.addResult(QP_TEST_RESULT_PASS, "Pass");
2025 case LINEINTERPOLATION_PROJECTED:
2026 // line interpolation weights are otherwise correct, but they are projected onto major axis
2027 m_testCtx.getLog() << tcu::TestLog::Message
2028 << "Interpolation was calculated using coordinates projected onto major axis. "
2029 "This method does not produce the same values as the non-projecting method defined in the specification."
2030 << tcu::TestLog::EndMessage;
2031 m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Interpolation was calculated using projected coordinateds");
2034 case LINEINTERPOLATION_INCORRECT:
2035 if (scene.lineWidth != 1.0f && m_numSamples > 1)
2037 // multisampled wide lines might not be supported
2038 m_result.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Interpolation of multisampled wide lines failed");
2042 // line interpolation is incorrect
2043 m_result.addResult(QP_TEST_RESULT_FAIL, "Found invalid pixel values");
2054 m_testCtx.getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
2057 if (++m_iteration == m_iterationCount)
2059 m_result.setTestContextResult(m_testCtx);
2066 void LineInterpolationTest::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2068 // use only red, green and blue
2069 const tcu::Vec4 colors[] =
2071 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2072 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2073 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2076 de::Random rnd(123 + iteration * 1000 + (int)m_primitive);
2078 outVertices.resize(6);
2079 outColors.resize(6);
2081 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2083 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2084 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2085 outVertices[vtxNdx].z() = 0.0f;
2088 outVertices[vtxNdx].w() = 1.0f;
2091 const float w = rnd.getFloat(0.2f, 4.0f);
2093 outVertices[vtxNdx].x() *= w;
2094 outVertices[vtxNdx].y() *= w;
2095 outVertices[vtxNdx].z() *= w;
2096 outVertices[vtxNdx].w() = w;
2099 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2103 void LineInterpolationTest::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2105 switch (m_primitive)
2109 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
2111 LineSceneSpec::SceneLine line;
2112 line.positions[0] = vertices[vtxNdx + 0];
2113 line.positions[1] = vertices[vtxNdx + 1];
2117 line.colors[0] = colors[vtxNdx + 1];
2118 line.colors[1] = colors[vtxNdx + 1];
2122 line.colors[0] = colors[vtxNdx + 0];
2123 line.colors[1] = colors[vtxNdx + 1];
2126 outLines.push_back(line);
2133 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2135 LineSceneSpec::SceneLine line;
2136 line.positions[0] = vertices[vtxNdx + 0];
2137 line.positions[1] = vertices[vtxNdx + 1];
2141 line.colors[0] = colors[vtxNdx + 1];
2142 line.colors[1] = colors[vtxNdx + 1];
2146 line.colors[0] = colors[vtxNdx + 0];
2147 line.colors[1] = colors[vtxNdx + 1];
2150 outLines.push_back(line);
2157 for (int vtxNdx = 0; vtxNdx < (int)vertices.size(); ++vtxNdx)
2159 LineSceneSpec::SceneLine line;
2160 line.positions[0] = vertices[(vtxNdx + 0) % (int)vertices.size()];
2161 line.positions[1] = vertices[(vtxNdx + 1) % (int)vertices.size()];
2165 line.colors[0] = colors[(vtxNdx + 1) % (int)vertices.size()];
2166 line.colors[1] = colors[(vtxNdx + 1) % (int)vertices.size()];
2170 line.colors[0] = colors[(vtxNdx + 0) % (int)vertices.size()];
2171 line.colors[1] = colors[(vtxNdx + 1) % (int)vertices.size()];
2174 outLines.push_back(line);
2184 float LineInterpolationTest::getLineWidth (void) const
2186 return m_lineWidths[m_iteration];
2191 RasterizationTests::RasterizationTests (Context& context)
2192 : TestCaseGroup(context, "rasterization", "Rasterization Tests")
2196 RasterizationTests::~RasterizationTests (void)
2200 void RasterizationTests::init (void)
2204 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(m_testCtx, "primitives", "Primitive rasterization");
2206 addChild(primitives);
2208 primitives->addChild(new TrianglesCase (m_context, "triangles", "Render primitives as GL_TRIANGLES, verify rasterization result"));
2209 primitives->addChild(new TriangleStripCase (m_context, "triangle_strip", "Render primitives as GL_TRIANGLE_STRIP, verify rasterization result"));
2210 primitives->addChild(new TriangleFanCase (m_context, "triangle_fan", "Render primitives as GL_TRIANGLE_FAN, verify rasterization result"));
2211 primitives->addChild(new LinesCase (m_context, "lines", "Render primitives as GL_LINES, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2212 primitives->addChild(new LineStripCase (m_context, "line_strip", "Render primitives as GL_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2213 primitives->addChild(new LineLoopCase (m_context, "line_loop", "Render primitives as GL_LINE_LOOP, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2214 primitives->addChild(new LinesCase (m_context, "lines_wide", "Render primitives as GL_LINES with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2215 primitives->addChild(new LineStripCase (m_context, "line_strip_wide", "Render primitives as GL_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2216 primitives->addChild(new LineLoopCase (m_context, "line_loop_wide", "Render primitives as GL_LINE_LOOP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2217 primitives->addChild(new PointCase (m_context, "points", "Render primitives as GL_POINTS, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2222 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(m_testCtx, "fill_rules", "Primitive fill rules");
2224 addChild(fillRules);
2226 fillRules->addChild(new FillRuleCase(m_context, "basic_quad", "Verify fill rules", FillRuleCase::FILLRULECASE_BASIC));
2227 fillRules->addChild(new FillRuleCase(m_context, "basic_quad_reverse", "Verify fill rules", FillRuleCase::FILLRULECASE_REVERSED));
2228 fillRules->addChild(new FillRuleCase(m_context, "clipped_full", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_FULL));
2229 fillRules->addChild(new FillRuleCase(m_context, "clipped_partly", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_PARTIAL));
2230 fillRules->addChild(new FillRuleCase(m_context, "projected", "Verify fill rules", FillRuleCase::FILLRULECASE_PROJECTED));
2235 static const struct CullMode
2241 { GL_FRONT, "front_" },
2242 { GL_BACK, "back_" },
2243 { GL_FRONT_AND_BACK, "both_" },
2245 static const struct PrimitiveType
2249 } primitiveTypes[] =
2251 { GL_TRIANGLES, "triangles" },
2252 { GL_TRIANGLE_STRIP, "triangle_strip" },
2253 { GL_TRIANGLE_FAN, "triangle_fan" },
2255 static const struct FrontFaceOrder
2258 const char* postfix;
2262 { GL_CW, "_reverse" },
2265 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(m_testCtx, "culling", "Culling");
2269 for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx)
2270 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
2271 for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx)
2273 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix;
2275 culling->addChild(new CullingTest(m_context, name.c_str(), "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode));
2281 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(m_testCtx, "interpolation", "Test interpolation");
2283 addChild(interpolation);
2287 tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(m_testCtx, "basic", "Non-projective interpolation");
2289 interpolation->addChild(basic);
2291 basic->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_NONE));
2292 basic->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip interpolation", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE));
2293 basic->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan interpolation", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE));
2294 basic->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2295 basic->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2296 basic->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2297 basic->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2298 basic->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2299 basic->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2304 tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(m_testCtx, "projected", "Projective interpolation");
2306 interpolation->addChild(projected);
2308 projected->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_PROJECTED));
2309 projected->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip interpolation", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED));
2310 projected->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan interpolation", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED));
2311 projected->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2312 projected->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2313 projected->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2314 projected->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2315 projected->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2316 projected->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2322 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(m_testCtx, "flatshading", "Test flatshading");
2324 addChild(flatshading);
2326 flatshading->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle flatshading", GL_TRIANGLES, INTERPOLATIONFLAGS_FLATSHADE));
2327 flatshading->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip flatshading", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_FLATSHADE));
2328 flatshading->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan flatshading", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_FLATSHADE));
2329 flatshading->addChild(new LineInterpolationTest (m_context, "lines", "Verify line flatshading", GL_LINES, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2330 flatshading->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip flatshading", GL_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2331 flatshading->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop flatshading", GL_LINE_LOOP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2332 flatshading->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line flatshading", GL_LINES, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2333 flatshading->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip flatshading", GL_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2334 flatshading->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop flatshading", GL_LINE_LOOP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2342 BaseRenderingCase::RenderTarget target;
2346 { "texture_2d", BaseRenderingCase::RENDERTARGET_TEXTURE_2D, -1 },
2347 { "rbo_singlesample", BaseRenderingCase::RENDERTARGET_RBO_SINGLESAMPLE, -1 },
2348 { "rbo_multisample_4", BaseRenderingCase::RENDERTARGET_RBO_MULTISAMPLE, 4 },
2349 { "rbo_multisample_max", BaseRenderingCase::RENDERTARGET_RBO_MULTISAMPLE, BaseRenderingCase::SAMPLE_COUNT_MAX },
2352 tcu::TestCaseGroup* const fboGroup = new tcu::TestCaseGroup(m_testCtx, "fbo", "Test using framebuffer objects");
2356 // .rbo_singlesample
2357 // .rbo_multisample_4
2358 // .rbo_multisample_max
2359 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(renderTargets); ++targetNdx)
2361 tcu::TestCaseGroup* const colorAttachmentGroup = new tcu::TestCaseGroup(m_testCtx, renderTargets[targetNdx].name, ("Test using " + std::string(renderTargets[targetNdx].name) + " color attachment").c_str());
2362 fboGroup->addChild(colorAttachmentGroup);
2366 tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(m_testCtx, "primitives", "Primitive rasterization");
2367 colorAttachmentGroup->addChild(primitiveGroup);
2369 primitiveGroup->addChild(new TrianglesCase (m_context, "triangles", "Render primitives as GL_TRIANGLES, verify rasterization result", renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2370 primitiveGroup->addChild(new LinesCase (m_context, "lines", "Render primitives as GL_LINES, verify rasterization result", PRIMITIVEWIDENESS_NARROW, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2371 primitiveGroup->addChild(new LinesCase (m_context, "lines_wide", "Render primitives as GL_LINES with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2372 primitiveGroup->addChild(new PointCase (m_context, "points", "Render primitives as GL_POINTS, verify rasterization result", PRIMITIVEWIDENESS_WIDE, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2377 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(m_testCtx, "fill_rules", "Primitive fill rules");
2379 colorAttachmentGroup->addChild(fillRules);
2381 fillRules->addChild(new FillRuleCase(m_context, "basic_quad", "Verify fill rules", FillRuleCase::FILLRULECASE_BASIC, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2382 fillRules->addChild(new FillRuleCase(m_context, "basic_quad_reverse", "Verify fill rules", FillRuleCase::FILLRULECASE_REVERSED, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2383 fillRules->addChild(new FillRuleCase(m_context, "clipped_full", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_FULL, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2384 fillRules->addChild(new FillRuleCase(m_context, "clipped_partly", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_PARTIAL, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2385 fillRules->addChild(new FillRuleCase(m_context, "projected", "Verify fill rules", FillRuleCase::FILLRULECASE_PROJECTED, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2390 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(m_testCtx, "interpolation", "Non-projective interpolation");
2392 colorAttachmentGroup->addChild(interpolation);
2394 interpolation->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_NONE, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2395 interpolation->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2396 interpolation->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));