am ea702448: am d38c14ba: am 75e63782: am 523bdab6: am 4667bcc1: am f55476d8: Remove...
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fFboStencilbufferTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *//*!
20  * \file
21  * \brief FBO stencilbuffer tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fFboStencilbufferTests.hpp"
25 #include "es3fFboTestCase.hpp"
26 #include "es3fFboTestUtil.hpp"
27 #include "gluTextureUtil.hpp"
28 #include "tcuTextureUtil.hpp"
29 #include "sglrContextUtil.hpp"
30 #include "glwEnums.hpp"
31
32 namespace deqp
33 {
34 namespace gles3
35 {
36 namespace Functional
37 {
38
39 using std::string;
40 using tcu::Vec2;
41 using tcu::Vec3;
42 using tcu::Vec4;
43 using tcu::IVec2;
44 using tcu::IVec3;
45 using tcu::IVec4;
46 using tcu::UVec4;
47 using namespace FboTestUtil;
48
49 class BasicFboStencilCase : public FboTestCase
50 {
51 public:
52         BasicFboStencilCase (Context& context, const char* name, const char* desc, deUint32 format, IVec2 size, bool useDepth)
53                 : FboTestCase   (context, name, desc)
54                 , m_format              (format)
55                 , m_size                (size)
56                 , m_useDepth    (useDepth)
57         {
58         }
59
60 protected:
61         void preCheck (void)
62         {
63                 checkFormatSupport(m_format);
64         }
65
66         void render (tcu::Surface& dst)
67         {
68                 const deUint32                  colorFormat             = GL_RGBA8;
69
70                 GradientShader                  gradShader              (glu::TYPE_FLOAT_VEC4);
71                 FlatColorShader                 flatShader              (glu::TYPE_FLOAT_VEC4);
72                 deUint32                                flatShaderID    = getCurrentContext()->createProgram(&flatShader);
73                 deUint32                                gradShaderID    = getCurrentContext()->createProgram(&gradShader);
74
75                 deUint32                                fbo                             = 0;
76                 deUint32                                colorRbo                = 0;
77                 deUint32                                depthStencilRbo = 0;
78
79                 // Colorbuffer.
80                 glGenRenderbuffers(1, &colorRbo);
81                 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
82                 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_size.x(), m_size.y());
83
84                 // Stencil (and depth) buffer.
85                 glGenRenderbuffers(1, &depthStencilRbo);
86                 glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRbo);
87                 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_size.x(), m_size.y());
88
89                 // Framebuffer.
90                 glGenFramebuffers(1, &fbo);
91                 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
92                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
93                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
94                 if (m_useDepth)
95                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
96                 checkError();
97                 checkFramebufferStatus(GL_FRAMEBUFFER);
98
99                 glViewport(0, 0, m_size.x(), m_size.y());
100
101                 // Clear framebuffer.
102                 glClearBufferfv(GL_COLOR, 0, Vec4(0.0f).getPtr());
103                 glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
104
105                 // Render intersecting quads - increment stencil on depth pass
106                 glEnable(GL_DEPTH_TEST);
107                 glEnable(GL_STENCIL_TEST);
108                 glStencilFunc(GL_ALWAYS, 0, 0xffu);
109                 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
110
111                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
112                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f,  0.0f), Vec3(+1.0f, +1.0f,  0.0f));
113
114                 gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
115                 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(+1.0f, +1.0f, +1.0f));
116
117                 glDisable(GL_DEPTH_TEST);
118
119                 // Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure
120                 glStencilFunc(GL_EQUAL, m_useDepth ? 2 : 1, 0xffu);
121                 glStencilOp(GL_DECR, GL_KEEP, GL_KEEP);
122
123                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0));
124                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(+0.5f, +0.5f, 0.0f));
125
126                 // Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer
127                 glStencilFunc(GL_GREATER, m_useDepth ? 1 : 2, 0xffu);
128
129                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
130                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
131
132                 readPixels(dst, 0, 0, m_size.x(), m_size.y(), glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
133         }
134
135 private:
136         deUint32        m_format;
137         IVec2           m_size;
138         bool            m_useDepth;
139 };
140
141 class DepthStencilAttachCase : public FboTestCase
142 {
143 public:
144         DepthStencilAttachCase (Context& context, const char* name, const char* desc, deUint32 attachDepth, deUint32 attachStencil)
145                 : FboTestCase           (context, name, desc)
146                 , m_attachDepth         (attachDepth)
147                 , m_attachStencil       (attachStencil)
148         {
149                 DE_ASSERT(m_attachDepth == GL_DEPTH_ATTACHMENT || m_attachDepth == GL_DEPTH_STENCIL_ATTACHMENT || m_attachDepth == GL_NONE);
150                 DE_ASSERT(m_attachStencil == GL_STENCIL_ATTACHMENT || m_attachStencil == GL_NONE);
151                 DE_ASSERT(m_attachDepth != GL_DEPTH_STENCIL || m_attachStencil == GL_NONE);
152         }
153
154 protected:
155         void render (tcu::Surface& dst)
156         {
157                 const deUint32                  colorFormat                     = GL_RGBA8;
158                 const deUint32                  depthStencilFormat      = GL_DEPTH24_STENCIL8;
159                 const int                               width                           = 128;
160                 const int                               height                          = 128;
161                 const bool                              hasDepth                        = (m_attachDepth == GL_DEPTH_STENCIL || m_attachDepth == GL_DEPTH_ATTACHMENT);
162 //              const bool                              hasStencil                      = (m_attachDepth == GL_DEPTH_STENCIL || m_attachStencil == GL_DEPTH_STENCIL_ATTACHMENT);
163
164                 GradientShader                  gradShader                      (glu::TYPE_FLOAT_VEC4);
165                 FlatColorShader                 flatShader                      (glu::TYPE_FLOAT_VEC4);
166                 deUint32                                flatShaderID            = getCurrentContext()->createProgram(&flatShader);
167                 deUint32                                gradShaderID            = getCurrentContext()->createProgram(&gradShader);
168
169                 deUint32                                fbo                                     = 0;
170                 deUint32                                colorRbo                        = 0;
171                 deUint32                                depthStencilRbo         = 0;
172
173                 // Colorbuffer.
174                 glGenRenderbuffers(1, &colorRbo);
175                 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
176                 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height);
177
178                 // Depth-stencil buffer.
179                 glGenRenderbuffers(1, &depthStencilRbo);
180                 glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRbo);
181                 glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
182
183                 // Framebuffer.
184                 glGenFramebuffers(1, &fbo);
185                 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
186                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
187
188                 if (m_attachDepth != GL_NONE)
189                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, m_attachDepth, GL_RENDERBUFFER, depthStencilRbo);
190                 if (m_attachStencil != GL_NONE)
191                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, m_attachStencil, GL_RENDERBUFFER, depthStencilRbo);
192
193                 checkError();
194                 checkFramebufferStatus(GL_FRAMEBUFFER);
195
196                 glViewport(0, 0, width, height);
197
198                 // Clear framebuffer.
199                 glClearBufferfv(GL_COLOR, 0, Vec4(0.0f).getPtr());
200                 glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
201
202                 // Render intersecting quads - increment stencil on depth pass
203                 glEnable(GL_DEPTH_TEST);
204                 glEnable(GL_STENCIL_TEST);
205                 glStencilFunc(GL_ALWAYS, 0, 0xffu);
206                 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
207
208                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
209                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f,  0.0f), Vec3(+1.0f, +1.0f,  0.0f));
210
211                 gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
212                 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(+1.0f, +1.0f, +1.0f));
213
214                 glDisable(GL_DEPTH_TEST);
215
216                 // Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure
217                 glStencilFunc(GL_EQUAL, hasDepth ? 2 : 1, 0xffu);
218                 glStencilOp(GL_DECR, GL_KEEP, GL_KEEP);
219
220                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0));
221                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(+0.5f, +0.5f, 0.0f));
222
223                 // Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer
224                 glStencilFunc(GL_GREATER, hasDepth ? 1 : 2, 0xffu);
225
226                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
227                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
228
229                 readPixels(dst, 0, 0, width, height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
230         }
231
232 private:
233         deUint32                m_attachDepth;
234         deUint32                m_attachStencil;
235 };
236
237 FboStencilTests::FboStencilTests (Context& context)
238         : TestCaseGroup(context, "stencil", "FBO Stencilbuffer tests")
239 {
240 }
241
242 FboStencilTests::~FboStencilTests (void)
243 {
244 }
245
246 void FboStencilTests::init (void)
247 {
248         static const deUint32 stencilFormats[] =
249         {
250                 GL_DEPTH32F_STENCIL8,
251                 GL_DEPTH24_STENCIL8,
252                 GL_STENCIL_INDEX8
253         };
254
255         // .basic
256         {
257                 tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic stencil tests");
258                 addChild(basicGroup);
259
260                 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(stencilFormats); fmtNdx++)
261                 {
262                         deUint32                        format          = stencilFormats[fmtNdx];
263                         tcu::TextureFormat      texFmt          = glu::mapGLInternalFormat(format);
264
265                         basicGroup->addChild(new BasicFboStencilCase(m_context, getFormatName(format), "", format, IVec2(111, 132), false));
266
267                         if (texFmt.order == tcu::TextureFormat::DS)
268                                 basicGroup->addChild(new BasicFboStencilCase(m_context, (string(getFormatName(format)) + "_depth").c_str(), "", format, IVec2(111, 132), true));
269                 }
270         }
271
272         // .attach
273         {
274                 tcu::TestCaseGroup* attachGroup = new tcu::TestCaseGroup(m_testCtx, "attach", "Attaching depth stencil");
275                 addChild(attachGroup);
276
277                 attachGroup->addChild(new DepthStencilAttachCase(m_context, "depth_only",                               "Only depth part of depth-stencil RBO attached",                        GL_DEPTH_ATTACHMENT,                    GL_NONE));
278                 attachGroup->addChild(new DepthStencilAttachCase(m_context, "stencil_only",                             "Only stencil part of depth-stencil RBO attached",                      GL_NONE,                                                GL_STENCIL_ATTACHMENT));
279                 attachGroup->addChild(new DepthStencilAttachCase(m_context, "depth_stencil_separate",   "Depth and stencil attached separately",                                        GL_DEPTH_ATTACHMENT,                    GL_STENCIL_ATTACHMENT));
280                 attachGroup->addChild(new DepthStencilAttachCase(m_context, "depth_stencil_attachment", "Depth and stencil attached with DEPTH_STENCIL_ATTACHMENT",     GL_DEPTH_STENCIL_ATTACHMENT,    GL_NONE));
281         }
282 }
283
284 } // Functional
285 } // gles3
286 } // deqp