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 float m_maxLineWidth;
514 std::vector<float> m_lineWidths;
517 BaseLineCase::BaseLineCase (Context& context, const char* name, const char* desc, glw::GLenum primitiveDrawType, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
518 : BaseRenderingCase (context, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
520 , m_iterationCount (3)
521 , m_primitiveDrawType (primitiveDrawType)
522 , m_primitiveWideness (wideness)
523 , m_allIterationsPassed (true)
524 , m_maxLineWidth (1.0f)
526 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
529 BaseLineCase::~BaseLineCase (void)
533 void BaseLineCase::init (void)
535 // create line widths
536 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
538 m_lineWidths.resize(m_iterationCount, 1.0f);
540 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
542 float range[2] = { 0.0f, 0.0f };
543 m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
545 m_testCtx.getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
547 // no wide line support
548 if (range[1] <= 1.0f)
549 throw tcu::NotSupportedError("wide line support required");
551 // set hand picked sizes
552 m_lineWidths.push_back(5.0f);
553 m_lineWidths.push_back(10.0f);
554 m_lineWidths.push_back(range[1]);
555 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
557 m_maxLineWidth = range[1];
563 BaseRenderingCase::init();
566 BaseLineCase::IterateResult BaseLineCase::iterate (void)
568 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
569 const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription);
570 const float lineWidth = getLineWidth();
571 tcu::Surface resultImage (m_renderSize, m_renderSize);
572 std::vector<tcu::Vec4> drawBuffer;
573 std::vector<LineSceneSpec::SceneLine> lines;
576 if (lineWidth <= m_maxLineWidth)
579 generateLines(m_iteration, drawBuffer, lines);
582 drawPrimitives(resultImage, drawBuffer, m_primitiveDrawType);
587 RasterizationArguments args;
590 args.numSamples = m_numSamples;
591 args.subpixelBits = m_subpixelBits;
592 args.redBits = getPixelFormat().redBits;
593 args.greenBits = getPixelFormat().greenBits;
594 args.blueBits = getPixelFormat().blueBits;
596 scene.lines.swap(lines);
597 scene.lineWidth = lineWidth;
599 compareOk = verifyLineGroupRasterization(resultImage, scene, args, m_testCtx.getLog());
602 m_allIterationsPassed = false;
606 m_testCtx.getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
609 if (++m_iteration == m_iterationCount)
611 if (m_allIterationsPassed)
612 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
614 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization");
622 float BaseLineCase::getLineWidth (void) const
624 return m_lineWidths[m_iteration];
627 class PointCase : public BaseRenderingCase
630 PointCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
634 IterateResult iterate (void);
637 float getPointSize (void) const;
640 void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
643 const int m_iterationCount;
644 const PrimitiveWideness m_primitiveWideness;
645 bool m_allIterationsPassed;
647 float m_maxPointSize;
648 std::vector<float> m_pointSizes;
651 PointCase::PointCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
652 : BaseRenderingCase (context, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
654 , m_iterationCount (3)
655 , m_primitiveWideness (wideness)
656 , m_allIterationsPassed (true)
657 , m_maxPointSize (1.0f)
661 PointCase::~PointCase (void)
665 void PointCase::init (void)
667 // create point sizes
668 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
670 m_pointSizes.resize(m_iterationCount, 1.0f);
672 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
674 float range[2] = { 0.0f, 0.0f };
675 m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_POINT_SIZE_RANGE, range);
677 m_testCtx.getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
679 // no wide line support
680 if (range[1] <= 1.0f)
681 throw tcu::NotSupportedError("wide point support required");
683 // set hand picked sizes
684 m_pointSizes.push_back(10.0f);
685 m_pointSizes.push_back(25.0f);
686 m_pointSizes.push_back(range[1]);
687 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
689 m_maxPointSize = range[1];
695 BaseRenderingCase::init();
698 PointCase::IterateResult PointCase::iterate (void)
700 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
701 const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription);
702 const float pointSize = getPointSize();
703 tcu::Surface resultImage (m_renderSize, m_renderSize);
704 std::vector<tcu::Vec4> drawBuffer;
705 std::vector<PointSceneSpec::ScenePoint> points;
708 if (pointSize <= m_maxPointSize)
711 generatePoints(m_iteration, drawBuffer, points);
714 drawPrimitives(resultImage, drawBuffer, GL_POINTS);
719 RasterizationArguments args;
720 PointSceneSpec scene;
722 args.numSamples = m_numSamples;
723 args.subpixelBits = m_subpixelBits;
724 args.redBits = getPixelFormat().redBits;
725 args.greenBits = getPixelFormat().greenBits;
726 args.blueBits = getPixelFormat().blueBits;
728 scene.points.swap(points);
730 compareOk = verifyPointGroupRasterization(resultImage, scene, args, m_testCtx.getLog());
733 m_allIterationsPassed = false;
737 m_testCtx.getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
740 if (++m_iteration == m_iterationCount)
742 if (m_allIterationsPassed)
743 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
745 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rasterization");
753 float PointCase::getPointSize (void) const
755 return m_pointSizes[m_iteration];
758 void PointCase::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
765 // \note: these values are chosen arbitrarily
766 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
767 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
768 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
769 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
770 outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
771 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
775 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
776 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
777 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
778 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
779 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
780 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
784 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
785 outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f);
786 outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
787 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
788 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
789 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
793 outPoints.resize(outData.size());
794 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
796 outPoints[pointNdx].position = outData[pointNdx];
797 outPoints[pointNdx].pointSize = getPointSize();
801 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
802 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
803 m_testCtx.getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
806 class TrianglesCase : public BaseTriangleCase
809 TrianglesCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
810 ~TrianglesCase (void);
812 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
815 TrianglesCase::TrianglesCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
816 : BaseTriangleCase(context, name, desc, GL_TRIANGLES, renderTarget, numSamples)
820 TrianglesCase::~TrianglesCase (void)
825 void TrianglesCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
832 // \note: these values are chosen arbitrarily
833 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
834 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
835 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
836 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
837 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
838 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
842 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
843 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
844 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
845 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
846 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
847 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
851 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
852 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
853 outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
854 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
855 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
856 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
860 outTriangles.resize(2);
861 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
862 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
863 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
865 outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false;
866 outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false;
867 outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false;
870 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
871 for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
874 << tcu::TestLog::Message
875 << "Triangle " << (triangleNdx+1) << ":"
876 << "\n\t" << outTriangles[triangleNdx].positions[0]
877 << "\n\t" << outTriangles[triangleNdx].positions[1]
878 << "\n\t" << outTriangles[triangleNdx].positions[2]
879 << tcu::TestLog::EndMessage;
883 class TriangleStripCase : public BaseTriangleCase
886 TriangleStripCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
888 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
891 TriangleStripCase::TriangleStripCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
892 : BaseTriangleCase(context, name, desc, GL_TRIANGLE_STRIP, renderTarget, numSamples)
896 void TriangleStripCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
903 // \note: these values are chosen arbitrarily
904 outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f);
905 outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f);
906 outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f);
907 outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f);
908 outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f);
912 outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f);
913 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
914 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
915 outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f);
916 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
920 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
921 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
922 outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f);
923 outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f);
924 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
928 outTriangles.resize(3);
929 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
930 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true;
931 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
933 outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true;
934 outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false;
935 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
937 outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true;
938 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
939 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
942 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
943 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
946 << tcu::TestLog::Message
947 << "\t" << outData[vtxNdx]
948 << tcu::TestLog::EndMessage;
952 class TriangleFanCase : public BaseTriangleCase
955 TriangleFanCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
957 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
960 TriangleFanCase::TriangleFanCase (Context& context, const char* name, const char* desc, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
961 : BaseTriangleCase(context, name, desc, GL_TRIANGLE_FAN, renderTarget, numSamples)
965 void TriangleFanCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
972 // \note: these values are chosen arbitrarily
973 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
974 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
975 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
976 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
977 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
981 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
982 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
983 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
984 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
985 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
989 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
990 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
991 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
992 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
993 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
997 outTriangles.resize(3);
998 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
999 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1000 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true;
1002 outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true;
1003 outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false;
1004 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1006 outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true;
1007 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1008 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1011 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1012 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1015 << tcu::TestLog::Message
1016 << "\t" << outData[vtxNdx]
1017 << tcu::TestLog::EndMessage;
1021 class LinesCase : public BaseLineCase
1024 LinesCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1026 void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1029 LinesCase::LinesCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
1030 : BaseLineCase(context, name, desc, GL_LINES, wideness, renderTarget, numSamples)
1034 void LinesCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1041 // \note: these values are chosen arbitrarily
1042 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1043 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1044 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1045 outData[3] = tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f);
1046 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1047 outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
1051 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1052 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1053 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1054 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1055 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1056 outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
1060 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1061 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1062 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1063 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1064 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1065 outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
1070 outLines[0].positions[0] = outData[0];
1071 outLines[0].positions[1] = outData[1];
1072 outLines[1].positions[0] = outData[2];
1073 outLines[1].positions[1] = outData[3];
1074 outLines[2].positions[0] = outData[4];
1075 outLines[2].positions[1] = outData[5];
1078 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
1079 for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
1082 << tcu::TestLog::Message
1083 << "Line " << (lineNdx+1) << ":"
1084 << "\n\t" << outLines[lineNdx].positions[0]
1085 << "\n\t" << outLines[lineNdx].positions[1]
1086 << tcu::TestLog::EndMessage;
1090 class LineStripCase : public BaseLineCase
1093 LineStripCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1095 void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1098 LineStripCase::LineStripCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
1099 : BaseLineCase(context, name, desc, GL_LINE_STRIP, wideness, renderTarget, numSamples)
1103 void LineStripCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1110 // \note: these values are chosen arbitrarily
1111 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1112 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1113 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1114 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1118 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1119 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1120 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1121 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1125 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1126 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1127 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1128 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1133 outLines[0].positions[0] = outData[0];
1134 outLines[0].positions[1] = outData[1];
1135 outLines[1].positions[0] = outData[1];
1136 outLines[1].positions[1] = outData[2];
1137 outLines[2].positions[0] = outData[2];
1138 outLines[2].positions[1] = outData[3];
1141 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1142 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1145 << tcu::TestLog::Message
1146 << "\t" << outData[vtxNdx]
1147 << tcu::TestLog::EndMessage;
1151 class LineLoopCase : public BaseLineCase
1154 LineLoopCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1156 void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1159 LineLoopCase::LineLoopCase (Context& context, const char* name, const char* desc, PrimitiveWideness wideness, BaseRenderingCase::RenderTarget renderTarget, int numSamples)
1160 : BaseLineCase(context, name, desc, GL_LINE_LOOP, wideness, renderTarget, numSamples)
1164 void LineLoopCase::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1171 // \note: these values are chosen arbitrarily
1172 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1173 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1174 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1175 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1179 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1180 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1181 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1182 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1186 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1187 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1188 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1189 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1194 outLines[0].positions[0] = outData[0];
1195 outLines[0].positions[1] = outData[1];
1196 outLines[1].positions[0] = outData[1];
1197 outLines[1].positions[1] = outData[2];
1198 outLines[2].positions[0] = outData[2];
1199 outLines[2].positions[1] = outData[3];
1200 outLines[3].positions[0] = outData[3];
1201 outLines[3].positions[1] = outData[0];
1204 m_testCtx.getLog() << tcu::TestLog::Message << "Rendering line loop, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1205 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1208 << tcu::TestLog::Message
1209 << "\t" << outData[vtxNdx]
1210 << tcu::TestLog::EndMessage;
1214 class FillRuleCase : public BaseRenderingCase
1217 enum FillRuleCaseType
1219 FILLRULECASE_BASIC = 0,
1220 FILLRULECASE_REVERSED,
1221 FILLRULECASE_CLIPPED_FULL,
1222 FILLRULECASE_CLIPPED_PARTIAL,
1223 FILLRULECASE_PROJECTED,
1228 FillRuleCase (Context& ctx, const char* name, const char* desc, FillRuleCaseType type, RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1229 ~FillRuleCase (void);
1230 IterateResult iterate (void);
1233 int getRenderSize (FillRuleCase::FillRuleCaseType type) const;
1234 int getNumIterations (FillRuleCase::FillRuleCaseType type) const;
1235 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const;
1237 const FillRuleCaseType m_caseType;
1239 const int m_iterationCount;
1240 bool m_allIterationsPassed;
1244 FillRuleCase::FillRuleCase (Context& ctx, const char* name, const char* desc, FillRuleCaseType type, RenderTarget renderTarget, int numSamples)
1245 : BaseRenderingCase (ctx, name, desc, renderTarget, numSamples, getRenderSize(type))
1248 , m_iterationCount (getNumIterations(type))
1249 , m_allIterationsPassed (true)
1251 DE_ASSERT(type < FILLRULECASE_LAST);
1254 FillRuleCase::~FillRuleCase (void)
1259 FillRuleCase::IterateResult FillRuleCase::iterate (void)
1261 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1262 const tcu::ScopedLogSection section (m_testCtx.getLog(), iterationDescription, iterationDescription);
1263 const int thresholdRed = 1 << (8 - getPixelFormat().redBits);
1264 const int thresholdGreen = 1 << (8 - getPixelFormat().greenBits);
1265 const int thresholdBlue = 1 << (8 - getPixelFormat().blueBits);
1266 tcu::Surface resultImage (m_renderSize, m_renderSize);
1267 std::vector<tcu::Vec4> drawBuffer;
1268 bool imageShown = false;
1270 generateTriangles(m_iteration, drawBuffer);
1274 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1275 const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
1277 m_testCtx.getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
1279 gl.enable(GL_BLEND);
1280 gl.blendEquation(GL_FUNC_ADD);
1281 gl.blendFunc(GL_ONE, GL_ONE);
1282 drawPrimitives(resultImage, drawBuffer, colorBuffer, GL_TRIANGLES);
1285 // verify no overdraw
1287 const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255);
1288 bool overdraw = false;
1290 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
1292 for (int y = 0; y < resultImage.getHeight(); ++y)
1293 for (int x = 0; x < resultImage.getWidth(); ++x)
1295 const tcu::RGBA color = resultImage.getPixel(x, y);
1297 // color values are greater than triangle color? Allow lower values for multisampled edges and background.
1298 if ((color.getRed() - triangleColor.getRed()) > thresholdRed ||
1299 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
1300 (color.getBlue() - triangleColor.getBlue()) > thresholdBlue)
1306 m_testCtx.getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
1309 m_testCtx.getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1310 m_testCtx.getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1311 << tcu::TestLog::Image("Result", "Result", resultImage)
1312 << tcu::TestLog::EndImageSet;
1315 m_allIterationsPassed = false;
1319 // verify no missing fragments in the full viewport case
1320 if (m_caseType == FILLRULECASE_CLIPPED_FULL)
1322 bool missingFragments = false;
1324 m_testCtx.getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
1326 for (int y = 0; y < resultImage.getHeight(); ++y)
1327 for (int x = 0; x < resultImage.getWidth(); ++x)
1329 const tcu::RGBA color = resultImage.getPixel(x, y);
1331 // black? (background)
1332 if (color.getRed() <= thresholdRed ||
1333 color.getGreen() <= thresholdGreen ||
1334 color.getBlue() <= thresholdBlue)
1335 missingFragments = true;
1339 if (!missingFragments)
1340 m_testCtx.getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
1343 m_testCtx.getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1347 m_testCtx.getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1348 << tcu::TestLog::Image("Result", "Result", resultImage)
1349 << tcu::TestLog::EndImageSet;
1352 m_allIterationsPassed = false;
1357 if (++m_iteration == m_iterationCount)
1359 if (m_allIterationsPassed)
1360 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1362 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Found invalid pixels");
1370 int FillRuleCase::getRenderSize (FillRuleCase::FillRuleCaseType type) const
1372 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1373 return DEFAULT_RENDER_SIZE / 4;
1375 return DEFAULT_RENDER_SIZE;
1378 int FillRuleCase::getNumIterations (FillRuleCase::FillRuleCaseType type) const
1380 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1386 void FillRuleCase::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
1390 case FILLRULECASE_BASIC:
1391 case FILLRULECASE_REVERSED:
1392 case FILLRULECASE_PROJECTED:
1394 const int numRows = 4;
1395 const int numColumns = 4;
1396 const float quadSide = 0.15f;
1397 de::Random rnd (0xabcd);
1399 outData.resize(6 * numRows * numColumns);
1401 for (int col = 0; col < numColumns; ++col)
1402 for (int row = 0; row < numRows; ++row)
1404 const tcu::Vec2 center = tcu::Vec2((row + 0.5f) / numRows * 2.0f - 1.0f, (col + 0.5f) / numColumns * 2.0f - 1.0f);
1405 const float rotation = (iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
1406 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1407 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1408 const tcu::Vec2 quad[4] =
1410 center + sideH + sideV,
1411 center + sideH - sideV,
1412 center - sideH - sideV,
1413 center - sideH + sideV,
1416 if (m_caseType == FILLRULECASE_BASIC)
1418 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1419 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1420 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1421 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1422 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1423 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1425 else if (m_caseType == FILLRULECASE_REVERSED)
1427 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1428 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1429 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1430 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1431 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1432 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1434 else if (m_caseType == FILLRULECASE_PROJECTED)
1436 const float w0 = rnd.getFloat(0.1f, 4.0f);
1437 const float w1 = rnd.getFloat(0.1f, 4.0f);
1438 const float w2 = rnd.getFloat(0.1f, 4.0f);
1439 const float w3 = rnd.getFloat(0.1f, 4.0f);
1441 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1442 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
1443 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1444 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1445 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1446 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
1449 DE_ASSERT(DE_FALSE);
1455 case FILLRULECASE_CLIPPED_PARTIAL:
1456 case FILLRULECASE_CLIPPED_FULL:
1458 const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
1459 const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
1460 const float rotation = (iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
1461 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1462 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1463 const tcu::Vec2 quad[4] =
1465 center + sideH + sideV,
1466 center + sideH - sideV,
1467 center - sideH - sideV,
1468 center - sideH + sideV,
1472 outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1473 outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1474 outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1475 outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1476 outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1477 outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1482 DE_ASSERT(DE_FALSE);
1486 class CullingTest : public BaseRenderingCase
1489 CullingTest (Context& ctx, const char* name, const char* desc, glw::GLenum cullMode, glw::GLenum primitive, glw::GLenum faceOrder);
1490 ~CullingTest (void);
1491 IterateResult iterate (void);
1494 void generateVertices (std::vector<tcu::Vec4>& outData) const;
1495 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
1496 bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
1498 const glw::GLenum m_cullMode;
1499 const glw::GLenum m_primitive;
1500 const glw::GLenum m_faceOrder;
1503 CullingTest::CullingTest (Context& ctx, const char* name, const char* desc, glw::GLenum cullMode, glw::GLenum primitive, glw::GLenum faceOrder)
1504 : BaseRenderingCase (ctx, name, desc, RENDERTARGET_DEFAULT, -1, DEFAULT_RENDER_SIZE)
1505 , m_cullMode (cullMode)
1506 , m_primitive (primitive)
1507 , m_faceOrder (faceOrder)
1511 CullingTest::~CullingTest (void)
1515 CullingTest::IterateResult CullingTest::iterate (void)
1517 tcu::Surface resultImage(m_renderSize, m_renderSize);
1518 std::vector<tcu::Vec4> drawBuffer;
1519 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1522 generateVertices(drawBuffer);
1523 extractTriangles(triangles, drawBuffer);
1527 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1529 gl.enable(GL_CULL_FACE);
1530 gl.cullFace(m_cullMode);
1531 gl.frontFace(m_faceOrder);
1533 m_testCtx.getLog() << tcu::TestLog::Message << "Setting front face to " << glu::getWindingName(m_faceOrder) << tcu::TestLog::EndMessage;
1534 m_testCtx.getLog() << tcu::TestLog::Message << "Setting cull face to " << glu::getFaceName(m_cullMode) << tcu::TestLog::EndMessage;
1535 m_testCtx.getLog() << tcu::TestLog::Message << "Drawing test pattern (" << glu::getPrimitiveTypeName(m_primitive) << ")" << tcu::TestLog::EndMessage;
1537 drawPrimitives(resultImage, drawBuffer, m_primitive);
1542 RasterizationArguments args;
1543 TriangleSceneSpec scene;
1545 args.numSamples = m_numSamples;
1546 args.subpixelBits = m_subpixelBits;
1547 args.redBits = getPixelFormat().redBits;
1548 args.greenBits = getPixelFormat().greenBits;
1549 args.blueBits = getPixelFormat().blueBits;
1551 scene.triangles.swap(triangles);
1553 if (verifyTriangleGroupRasterization(resultImage, scene, args, m_testCtx.getLog(), VERIFICATIONMODE_WEAK))
1554 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1556 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect rendering");
1562 void CullingTest::generateVertices (std::vector<tcu::Vec4>& outData) const
1564 de::Random rnd(543210);
1567 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1569 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
1570 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
1571 outData[vtxNdx].z() = 0.0f;
1572 outData[vtxNdx].w() = 1.0f;
1576 void CullingTest::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
1578 const bool cullDirection = (m_cullMode == GL_FRONT) ^ (m_faceOrder == GL_CCW);
1581 if (m_cullMode == GL_FRONT_AND_BACK)
1584 switch (m_primitive)
1588 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
1590 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
1591 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
1592 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
1594 if (triangleOrder(v0, v1, v2) != cullDirection)
1596 TriangleSceneSpec::SceneTriangle tri;
1597 tri.positions[0] = v0; tri.sharedEdge[0] = false;
1598 tri.positions[1] = v1; tri.sharedEdge[1] = false;
1599 tri.positions[2] = v2; tri.sharedEdge[2] = false;
1601 outTriangles.push_back(tri);
1607 case GL_TRIANGLE_STRIP:
1609 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
1611 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
1612 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
1613 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
1615 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
1617 TriangleSceneSpec::SceneTriangle tri;
1618 tri.positions[0] = v0; tri.sharedEdge[0] = false;
1619 tri.positions[1] = v1; tri.sharedEdge[1] = false;
1620 tri.positions[2] = v2; tri.sharedEdge[2] = false;
1622 outTriangles.push_back(tri);
1628 case GL_TRIANGLE_FAN:
1630 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
1632 const tcu::Vec4& v0 = vertices[0];
1633 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
1634 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
1636 if (triangleOrder(v0, v1, v2) != cullDirection)
1638 TriangleSceneSpec::SceneTriangle tri;
1639 tri.positions[0] = v0; tri.sharedEdge[0] = false;
1640 tri.positions[1] = v1; tri.sharedEdge[1] = false;
1641 tri.positions[2] = v2; tri.sharedEdge[2] = false;
1643 outTriangles.push_back(tri);
1654 bool CullingTest::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
1656 const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
1657 const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
1658 const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
1661 return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) < 0;
1664 class TriangleInterpolationTest : public BaseRenderingCase
1667 TriangleInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1668 ~TriangleInterpolationTest (void);
1669 IterateResult iterate (void);
1672 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
1673 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
1675 const glw::GLenum m_primitive;
1676 const bool m_projective;
1677 const int m_iterationCount;
1680 bool m_allIterationsPassed;
1683 TriangleInterpolationTest::TriangleInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, RenderTarget renderTarget, int numSamples)
1684 : BaseRenderingCase (ctx, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
1685 , m_primitive (primitive)
1686 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
1687 , m_iterationCount (3)
1689 , m_allIterationsPassed (true)
1691 m_flatshade = ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0);
1694 TriangleInterpolationTest::~TriangleInterpolationTest (void)
1699 TriangleInterpolationTest::IterateResult TriangleInterpolationTest::iterate (void)
1701 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1702 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
1703 tcu::Surface resultImage (m_renderSize, m_renderSize);
1704 std::vector<tcu::Vec4> drawBuffer;
1705 std::vector<tcu::Vec4> colorBuffer;
1706 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1709 generateVertices(m_iteration, drawBuffer, colorBuffer);
1710 extractTriangles(triangles, drawBuffer, colorBuffer);
1714 m_testCtx.getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
1715 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
1716 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
1720 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitive);
1724 RasterizationArguments args;
1725 TriangleSceneSpec scene;
1727 args.numSamples = m_numSamples;
1728 args.subpixelBits = m_subpixelBits;
1729 args.redBits = getPixelFormat().redBits;
1730 args.greenBits = getPixelFormat().greenBits;
1731 args.blueBits = getPixelFormat().blueBits;
1733 scene.triangles.swap(triangles);
1735 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_testCtx.getLog()))
1736 m_allIterationsPassed = false;
1740 if (++m_iteration == m_iterationCount)
1742 if (m_allIterationsPassed)
1743 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1745 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Found invalid pixel values");
1753 void TriangleInterpolationTest::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
1755 // use only red, green and blue
1756 const tcu::Vec4 colors[] =
1758 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
1759 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
1760 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
1763 de::Random rnd(123 + iteration * 1000 + (int)m_primitive);
1765 outVertices.resize(6);
1766 outColors.resize(6);
1768 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
1770 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
1771 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
1772 outVertices[vtxNdx].z() = 0.0f;
1775 outVertices[vtxNdx].w() = 1.0f;
1778 const float w = rnd.getFloat(0.2f, 4.0f);
1780 outVertices[vtxNdx].x() *= w;
1781 outVertices[vtxNdx].y() *= w;
1782 outVertices[vtxNdx].z() *= w;
1783 outVertices[vtxNdx].w() = w;
1786 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
1790 void TriangleInterpolationTest::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
1792 switch (m_primitive)
1796 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
1798 TriangleSceneSpec::SceneTriangle tri;
1799 tri.positions[0] = vertices[vtxNdx + 0];
1800 tri.positions[1] = vertices[vtxNdx + 1];
1801 tri.positions[2] = vertices[vtxNdx + 2];
1802 tri.sharedEdge[0] = false;
1803 tri.sharedEdge[1] = false;
1804 tri.sharedEdge[2] = false;
1808 tri.colors[0] = colors[vtxNdx + 2];
1809 tri.colors[1] = colors[vtxNdx + 2];
1810 tri.colors[2] = colors[vtxNdx + 2];
1814 tri.colors[0] = colors[vtxNdx + 0];
1815 tri.colors[1] = colors[vtxNdx + 1];
1816 tri.colors[2] = colors[vtxNdx + 2];
1819 outTriangles.push_back(tri);
1824 case GL_TRIANGLE_STRIP:
1826 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
1828 TriangleSceneSpec::SceneTriangle tri;
1829 tri.positions[0] = vertices[vtxNdx + 0];
1830 tri.positions[1] = vertices[vtxNdx + 1];
1831 tri.positions[2] = vertices[vtxNdx + 2];
1832 tri.sharedEdge[0] = false;
1833 tri.sharedEdge[1] = false;
1834 tri.sharedEdge[2] = false;
1838 tri.colors[0] = colors[vtxNdx + 2];
1839 tri.colors[1] = colors[vtxNdx + 2];
1840 tri.colors[2] = colors[vtxNdx + 2];
1844 tri.colors[0] = colors[vtxNdx + 0];
1845 tri.colors[1] = colors[vtxNdx + 1];
1846 tri.colors[2] = colors[vtxNdx + 2];
1849 outTriangles.push_back(tri);
1854 case GL_TRIANGLE_FAN:
1856 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
1858 TriangleSceneSpec::SceneTriangle tri;
1859 tri.positions[0] = vertices[0];
1860 tri.positions[1] = vertices[vtxNdx + 0];
1861 tri.positions[2] = vertices[vtxNdx + 1];
1862 tri.sharedEdge[0] = false;
1863 tri.sharedEdge[1] = false;
1864 tri.sharedEdge[2] = false;
1868 tri.colors[0] = colors[vtxNdx + 1];
1869 tri.colors[1] = colors[vtxNdx + 1];
1870 tri.colors[2] = colors[vtxNdx + 1];
1874 tri.colors[0] = colors[0];
1875 tri.colors[1] = colors[vtxNdx + 0];
1876 tri.colors[2] = colors[vtxNdx + 1];
1879 outTriangles.push_back(tri);
1889 class LineInterpolationTest : public BaseRenderingCase
1892 LineInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, PrimitiveWideness wideness, RenderTarget renderTarget = RENDERTARGET_DEFAULT, int numSamples = -1);
1893 ~LineInterpolationTest (void);
1896 IterateResult iterate (void);
1899 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
1900 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
1901 float getLineWidth (void) const;
1903 const glw::GLenum m_primitive;
1904 const bool m_projective;
1905 const int m_iterationCount;
1906 const PrimitiveWideness m_primitiveWideness;
1909 tcu::ResultCollector m_result;
1910 float m_maxLineWidth;
1911 std::vector<float> m_lineWidths;
1914 LineInterpolationTest::LineInterpolationTest (Context& ctx, const char* name, const char* desc, glw::GLenum primitive, int flags, PrimitiveWideness wideness, RenderTarget renderTarget, int numSamples)
1915 : BaseRenderingCase (ctx, name, desc, renderTarget, numSamples, DEFAULT_RENDER_SIZE)
1916 , m_primitive (primitive)
1917 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
1918 , m_iterationCount (3)
1919 , m_primitiveWideness (wideness)
1921 , m_maxLineWidth (1.0f)
1923 m_flatshade = ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0);
1926 LineInterpolationTest::~LineInterpolationTest (void)
1931 void LineInterpolationTest::init (void)
1933 // create line widths
1934 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1936 m_lineWidths.resize(m_iterationCount, 1.0f);
1938 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1940 float range[2] = { 0.0f, 0.0f };
1941 m_context.getRenderContext().getFunctions().getFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
1943 m_testCtx.getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1945 // no wide line support
1946 if (range[1] <= 1.0f)
1947 throw tcu::NotSupportedError("wide line support required");
1949 // set hand picked sizes
1950 m_lineWidths.push_back(5.0f);
1951 m_lineWidths.push_back(10.0f);
1952 m_lineWidths.push_back(range[1]);
1953 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1955 m_maxLineWidth = range[1];
1961 BaseRenderingCase::init();
1964 LineInterpolationTest::IterateResult LineInterpolationTest::iterate (void)
1966 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1967 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
1968 const float lineWidth = getLineWidth();
1969 tcu::Surface resultImage (m_renderSize, m_renderSize);
1970 std::vector<tcu::Vec4> drawBuffer;
1971 std::vector<tcu::Vec4> colorBuffer;
1972 std::vector<LineSceneSpec::SceneLine> lines;
1975 if (lineWidth <= m_maxLineWidth)
1978 generateVertices(m_iteration, drawBuffer, colorBuffer);
1979 extractLines(lines, drawBuffer, colorBuffer);
1983 m_testCtx.getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
1984 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
1985 m_testCtx.getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
1989 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitive);
1993 RasterizationArguments args;
1994 LineSceneSpec scene;
1995 LineInterpolationMethod iterationResult;
1997 args.numSamples = m_numSamples;
1998 args.subpixelBits = m_subpixelBits;
1999 args.redBits = getPixelFormat().redBits;
2000 args.greenBits = getPixelFormat().greenBits;
2001 args.blueBits = getPixelFormat().blueBits;
2003 scene.lines.swap(lines);
2004 scene.lineWidth = getLineWidth();
2006 iterationResult = verifyLineGroupInterpolation(resultImage, scene, args, m_testCtx.getLog());
2007 switch (iterationResult)
2009 case LINEINTERPOLATION_STRICTLY_CORRECT:
2010 // line interpolation matches the specification
2011 m_result.addResult(QP_TEST_RESULT_PASS, "Pass");
2014 case LINEINTERPOLATION_PROJECTED:
2015 // line interpolation weights are otherwise correct, but they are projected onto major axis
2016 m_testCtx.getLog() << tcu::TestLog::Message
2017 << "Interpolation was calculated using coordinates projected onto major axis. "
2018 "This method does not produce the same values as the non-projecting method defined in the specification."
2019 << tcu::TestLog::EndMessage;
2020 m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Interpolation was calculated using projected coordinateds");
2023 case LINEINTERPOLATION_INCORRECT:
2024 // line interpolation is incorrect
2025 m_result.addResult(QP_TEST_RESULT_FAIL, "Found invalid pixel values");
2035 m_testCtx.getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
2038 if (++m_iteration == m_iterationCount)
2040 m_result.setTestContextResult(m_testCtx);
2047 void LineInterpolationTest::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2049 // use only red, green and blue
2050 const tcu::Vec4 colors[] =
2052 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2053 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2054 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2057 de::Random rnd(123 + iteration * 1000 + (int)m_primitive);
2059 outVertices.resize(6);
2060 outColors.resize(6);
2062 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2064 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2065 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2066 outVertices[vtxNdx].z() = 0.0f;
2069 outVertices[vtxNdx].w() = 1.0f;
2072 const float w = rnd.getFloat(0.2f, 4.0f);
2074 outVertices[vtxNdx].x() *= w;
2075 outVertices[vtxNdx].y() *= w;
2076 outVertices[vtxNdx].z() *= w;
2077 outVertices[vtxNdx].w() = w;
2080 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2084 void LineInterpolationTest::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2086 switch (m_primitive)
2090 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
2092 LineSceneSpec::SceneLine line;
2093 line.positions[0] = vertices[vtxNdx + 0];
2094 line.positions[1] = vertices[vtxNdx + 1];
2098 line.colors[0] = colors[vtxNdx + 1];
2099 line.colors[1] = colors[vtxNdx + 1];
2103 line.colors[0] = colors[vtxNdx + 0];
2104 line.colors[1] = colors[vtxNdx + 1];
2107 outLines.push_back(line);
2114 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2116 LineSceneSpec::SceneLine line;
2117 line.positions[0] = vertices[vtxNdx + 0];
2118 line.positions[1] = vertices[vtxNdx + 1];
2122 line.colors[0] = colors[vtxNdx + 1];
2123 line.colors[1] = colors[vtxNdx + 1];
2127 line.colors[0] = colors[vtxNdx + 0];
2128 line.colors[1] = colors[vtxNdx + 1];
2131 outLines.push_back(line);
2138 for (int vtxNdx = 0; vtxNdx < (int)vertices.size(); ++vtxNdx)
2140 LineSceneSpec::SceneLine line;
2141 line.positions[0] = vertices[(vtxNdx + 0) % (int)vertices.size()];
2142 line.positions[1] = vertices[(vtxNdx + 1) % (int)vertices.size()];
2146 line.colors[0] = colors[(vtxNdx + 1) % (int)vertices.size()];
2147 line.colors[1] = colors[(vtxNdx + 1) % (int)vertices.size()];
2151 line.colors[0] = colors[(vtxNdx + 0) % (int)vertices.size()];
2152 line.colors[1] = colors[(vtxNdx + 1) % (int)vertices.size()];
2155 outLines.push_back(line);
2165 float LineInterpolationTest::getLineWidth (void) const
2167 return m_lineWidths[m_iteration];
2172 RasterizationTests::RasterizationTests (Context& context)
2173 : TestCaseGroup(context, "rasterization", "Rasterization Tests")
2177 RasterizationTests::~RasterizationTests (void)
2181 void RasterizationTests::init (void)
2185 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(m_testCtx, "primitives", "Primitive rasterization");
2187 addChild(primitives);
2189 primitives->addChild(new TrianglesCase (m_context, "triangles", "Render primitives as GL_TRIANGLES, verify rasterization result"));
2190 primitives->addChild(new TriangleStripCase (m_context, "triangle_strip", "Render primitives as GL_TRIANGLE_STRIP, verify rasterization result"));
2191 primitives->addChild(new TriangleFanCase (m_context, "triangle_fan", "Render primitives as GL_TRIANGLE_FAN, verify rasterization result"));
2192 primitives->addChild(new LinesCase (m_context, "lines", "Render primitives as GL_LINES, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2193 primitives->addChild(new LineStripCase (m_context, "line_strip", "Render primitives as GL_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2194 primitives->addChild(new LineLoopCase (m_context, "line_loop", "Render primitives as GL_LINE_LOOP, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2195 primitives->addChild(new LinesCase (m_context, "lines_wide", "Render primitives as GL_LINES with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2196 primitives->addChild(new LineStripCase (m_context, "line_strip_wide", "Render primitives as GL_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2197 primitives->addChild(new LineLoopCase (m_context, "line_loop_wide", "Render primitives as GL_LINE_LOOP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2198 primitives->addChild(new PointCase (m_context, "points", "Render primitives as GL_POINTS, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2203 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(m_testCtx, "fill_rules", "Primitive fill rules");
2205 addChild(fillRules);
2207 fillRules->addChild(new FillRuleCase(m_context, "basic_quad", "Verify fill rules", FillRuleCase::FILLRULECASE_BASIC));
2208 fillRules->addChild(new FillRuleCase(m_context, "basic_quad_reverse", "Verify fill rules", FillRuleCase::FILLRULECASE_REVERSED));
2209 fillRules->addChild(new FillRuleCase(m_context, "clipped_full", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_FULL));
2210 fillRules->addChild(new FillRuleCase(m_context, "clipped_partly", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_PARTIAL));
2211 fillRules->addChild(new FillRuleCase(m_context, "projected", "Verify fill rules", FillRuleCase::FILLRULECASE_PROJECTED));
2216 static const struct CullMode
2222 { GL_FRONT, "front_" },
2223 { GL_BACK, "back_" },
2224 { GL_FRONT_AND_BACK, "both_" },
2226 static const struct PrimitiveType
2230 } primitiveTypes[] =
2232 { GL_TRIANGLES, "triangles" },
2233 { GL_TRIANGLE_STRIP, "triangle_strip" },
2234 { GL_TRIANGLE_FAN, "triangle_fan" },
2236 static const struct FrontFaceOrder
2239 const char* postfix;
2243 { GL_CW, "_reverse" },
2246 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(m_testCtx, "culling", "Culling");
2250 for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx)
2251 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
2252 for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx)
2254 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix;
2256 culling->addChild(new CullingTest(m_context, name.c_str(), "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode));
2262 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(m_testCtx, "interpolation", "Test interpolation");
2264 addChild(interpolation);
2268 tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(m_testCtx, "basic", "Non-projective interpolation");
2270 interpolation->addChild(basic);
2272 basic->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_NONE));
2273 basic->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip interpolation", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE));
2274 basic->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan interpolation", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE));
2275 basic->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2276 basic->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2277 basic->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2278 basic->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2279 basic->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2280 basic->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2285 tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(m_testCtx, "projected", "Projective interpolation");
2287 interpolation->addChild(projected);
2289 projected->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_PROJECTED));
2290 projected->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip interpolation", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED));
2291 projected->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan interpolation", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED));
2292 projected->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2293 projected->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2294 projected->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2295 projected->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2296 projected->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip interpolation", GL_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2297 projected->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop interpolation", GL_LINE_LOOP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2303 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(m_testCtx, "flatshading", "Test flatshading");
2305 addChild(flatshading);
2307 flatshading->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle flatshading", GL_TRIANGLES, INTERPOLATIONFLAGS_FLATSHADE));
2308 flatshading->addChild(new TriangleInterpolationTest (m_context, "triangle_strip", "Verify triangle strip flatshading", GL_TRIANGLE_STRIP, INTERPOLATIONFLAGS_FLATSHADE));
2309 flatshading->addChild(new TriangleInterpolationTest (m_context, "triangle_fan", "Verify triangle fan flatshading", GL_TRIANGLE_FAN, INTERPOLATIONFLAGS_FLATSHADE));
2310 flatshading->addChild(new LineInterpolationTest (m_context, "lines", "Verify line flatshading", GL_LINES, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2311 flatshading->addChild(new LineInterpolationTest (m_context, "line_strip", "Verify line strip flatshading", GL_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2312 flatshading->addChild(new LineInterpolationTest (m_context, "line_loop", "Verify line loop flatshading", GL_LINE_LOOP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2313 flatshading->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line flatshading", GL_LINES, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2314 flatshading->addChild(new LineInterpolationTest (m_context, "line_strip_wide", "Verify wide line strip flatshading", GL_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2315 flatshading->addChild(new LineInterpolationTest (m_context, "line_loop_wide", "Verify wide line loop flatshading", GL_LINE_LOOP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2323 BaseRenderingCase::RenderTarget target;
2327 { "texture_2d", BaseRenderingCase::RENDERTARGET_TEXTURE_2D, -1 },
2328 { "rbo_singlesample", BaseRenderingCase::RENDERTARGET_RBO_SINGLESAMPLE, -1 },
2329 { "rbo_multisample_4", BaseRenderingCase::RENDERTARGET_RBO_MULTISAMPLE, 4 },
2330 { "rbo_multisample_max", BaseRenderingCase::RENDERTARGET_RBO_MULTISAMPLE, BaseRenderingCase::SAMPLE_COUNT_MAX },
2333 tcu::TestCaseGroup* const fboGroup = new tcu::TestCaseGroup(m_testCtx, "fbo", "Test using framebuffer objects");
2337 // .rbo_singlesample
2338 // .rbo_multisample_4
2339 // .rbo_multisample_max
2340 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(renderTargets); ++targetNdx)
2342 tcu::TestCaseGroup* const colorAttachmentGroup = new tcu::TestCaseGroup(m_testCtx, renderTargets[targetNdx].name, ("Test using " + std::string(renderTargets[targetNdx].name) + " color attachment").c_str());
2343 fboGroup->addChild(colorAttachmentGroup);
2347 tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(m_testCtx, "primitives", "Primitive rasterization");
2348 colorAttachmentGroup->addChild(primitiveGroup);
2350 primitiveGroup->addChild(new TrianglesCase (m_context, "triangles", "Render primitives as GL_TRIANGLES, verify rasterization result", renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2351 primitiveGroup->addChild(new LinesCase (m_context, "lines", "Render primitives as GL_LINES, verify rasterization result", PRIMITIVEWIDENESS_NARROW, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2352 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));
2353 primitiveGroup->addChild(new PointCase (m_context, "points", "Render primitives as GL_POINTS, verify rasterization result", PRIMITIVEWIDENESS_WIDE, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2358 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(m_testCtx, "fill_rules", "Primitive fill rules");
2360 colorAttachmentGroup->addChild(fillRules);
2362 fillRules->addChild(new FillRuleCase(m_context, "basic_quad", "Verify fill rules", FillRuleCase::FILLRULECASE_BASIC, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2363 fillRules->addChild(new FillRuleCase(m_context, "basic_quad_reverse", "Verify fill rules", FillRuleCase::FILLRULECASE_REVERSED, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2364 fillRules->addChild(new FillRuleCase(m_context, "clipped_full", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_FULL, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2365 fillRules->addChild(new FillRuleCase(m_context, "clipped_partly", "Verify fill rules", FillRuleCase::FILLRULECASE_CLIPPED_PARTIAL, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2366 fillRules->addChild(new FillRuleCase(m_context, "projected", "Verify fill rules", FillRuleCase::FILLRULECASE_PROJECTED, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2371 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(m_testCtx, "interpolation", "Non-projective interpolation");
2373 colorAttachmentGroup->addChild(interpolation);
2375 interpolation->addChild(new TriangleInterpolationTest (m_context, "triangles", "Verify triangle interpolation", GL_TRIANGLES, INTERPOLATIONFLAGS_NONE, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2376 interpolation->addChild(new LineInterpolationTest (m_context, "lines", "Verify line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));
2377 interpolation->addChild(new LineInterpolationTest (m_context, "lines_wide", "Verify wide line interpolation", GL_LINES, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, renderTargets[targetNdx].target, renderTargets[targetNdx].numSamples));