Render to FBO in tessellation winding order tests
authorSunny Sun <sunny.sun@arm.com>
Mon, 4 Sep 2017 04:22:59 +0000 (12:22 +0800)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 8 Sep 2017 07:08:42 +0000 (03:08 -0400)
Tessellation winding order tests render
to a new frame buffer to prevent
GL_INVALID_OPERATION from being generated
by glReadPixels.

VK-GL-CTS issue: 668

Components: OpenGL

Affects:
KHR-GL4*.tessellation_shader.winding.*
KHR-GLES3*.core.tessellation_shader.winding.*

Change-Id: Ia1af86df535ee07acd421ad1133497ce8f4e7eee

external/openglcts/modules/glesext/tessellation_shader/esextcTessellationShaderWinding.cpp

index 0a5792f..c5b80f8 100644 (file)
@@ -47,11 +47,14 @@ public:
        void              init(void);
        void              deinit(void);
        IterateResult iterate(void);
+       void prepareFramebuffer();
 
 private:
        static const int RENDER_SIZE = 64;
 
        de::SharedPtr<const glu::ShaderProgram> m_program;
+       glw::GLuint m_rbo;
+       glw::GLuint m_fbo;
 };
 
 WindingCase::WindingCase(glcts::Context& context, const ExtParameters& extParams, std::string name,
@@ -62,7 +65,9 @@ WindingCase::WindingCase(glcts::Context& context, const ExtParameters& extParams
        DE_ASSERT((winding.compare("cw") == 0) || (winding.compare("ccw") == 0));
 
        m_specializationMap["PRIMITIVE_TYPE"] = primitiveType;
-       m_specializationMap["WINDING"]            = winding;
+       m_specializationMap["WINDING"]        = winding;
+       m_rbo                                 = 0;
+       m_fbo                                 = 0;
 }
 
 void WindingCase::init(void)
@@ -120,9 +125,51 @@ void WindingCase::init(void)
 
 void WindingCase::deinit(void)
 {
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       if (m_fbo)
+       {
+               gl.deleteFramebuffers(1, &m_fbo);
+               m_fbo = 0;
+       }
+
+       if (m_rbo)
+       {
+               gl.deleteRenderbuffers(1, &m_rbo);
+               m_rbo = 0;
+       }
+
        m_program.clear();
 }
 
+/** @brief Bind default framebuffer object.
+ *
+ *  @note The function may throw if unexpected error has occured.
+ */
+void WindingCase::prepareFramebuffer()
+{
+       /* Shortcut for GL functionality */
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       gl.genRenderbuffers(1, &m_rbo);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");
+
+       gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");
+
+       gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDER_SIZE, RENDER_SIZE);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");
+
+       gl.genFramebuffers(1, &m_fbo);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
+
+       gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");
+}
+
 WindingCase::IterateResult WindingCase::iterate(void)
 {
        const glu::RenderContext& renderCtx = m_context.getRenderContext();
@@ -136,6 +183,7 @@ WindingCase::IterateResult WindingCase::iterate(void)
        const bool testWindingIsCW                              = (m_specializationMap["WINDING"].compare("cw") == 0);
        bool       success                                              = true;
 
+       prepareFramebuffer();
        gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
        gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
        gl.useProgram(programGL);