am 4648b953: (-s ours) am 323c5b2a: Remove infeasible M tests. am: 2028771a01
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fFboInvalidateTests.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 invalidate tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fFboInvalidateTests.hpp"
25 #include "es3fFboTestCase.hpp"
26 #include "es3fFboTestUtil.hpp"
27 #include "gluTextureUtil.hpp"
28 #include "tcuImageCompare.hpp"
29 #include "tcuTextureUtil.hpp"
30 #include "sglrContextUtil.hpp"
31
32 #include "glwEnums.hpp"
33
34 #include <algorithm>
35
36 namespace deqp
37 {
38 namespace gles3
39 {
40 namespace Functional
41 {
42
43 using std::string;
44 using std::vector;
45 using tcu::Vec2;
46 using tcu::Vec3;
47 using tcu::Vec4;
48 using tcu::IVec2;
49 using tcu::IVec3;
50 using tcu::IVec4;
51 using tcu::UVec4;
52 using namespace FboTestUtil;
53
54 static std::vector<deUint32> getDefaultFBDiscardAttachments (deUint32 discardBufferBits)
55 {
56         vector<deUint32> attachments;
57
58         if (discardBufferBits & GL_COLOR_BUFFER_BIT)
59                 attachments.push_back(GL_COLOR);
60
61         if (discardBufferBits & GL_DEPTH_BUFFER_BIT)
62                 attachments.push_back(GL_DEPTH);
63
64         if (discardBufferBits & GL_STENCIL_BUFFER_BIT)
65                 attachments.push_back(GL_STENCIL);
66
67         return attachments;
68 }
69
70 static std::vector<deUint32> getFBODiscardAttachments (deUint32 discardBufferBits)
71 {
72         vector<deUint32> attachments;
73
74         if (discardBufferBits & GL_COLOR_BUFFER_BIT)
75                 attachments.push_back(GL_COLOR_ATTACHMENT0);
76
77         // \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB
78         if ((discardBufferBits & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))
79                 attachments.push_back(GL_DEPTH_STENCIL_ATTACHMENT);
80         else if (discardBufferBits & GL_DEPTH_BUFFER_BIT)
81                 attachments.push_back(GL_DEPTH_ATTACHMENT);
82         else if (discardBufferBits & GL_STENCIL_BUFFER_BIT)
83                 attachments.push_back(GL_STENCIL_ATTACHMENT);
84
85         return attachments;
86 }
87
88 static inline bool hasAttachment (const std::vector<deUint32>& attachmentList, deUint32 attachment)
89 {
90         return std::find(attachmentList.begin(), attachmentList.end(), attachment) != attachmentList.end();
91 }
92
93 static deUint32 getCompatibleColorFormat (const tcu::RenderTarget& renderTargetInfo)
94 {
95         const tcu::PixelFormat& pxFmt = renderTargetInfo.getPixelFormat();
96         DE_ASSERT(de::inBounds(pxFmt.redBits,   0, 0xff) &&
97                           de::inBounds(pxFmt.greenBits, 0, 0xff) &&
98                           de::inBounds(pxFmt.blueBits,  0, 0xff) &&
99                           de::inBounds(pxFmt.alphaBits, 0, 0xff));
100
101 #define PACK_FMT(R, G, B, A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))
102
103         // \note [pyry] This may not hold true on some implementations - best effort guess only.
104         switch (PACK_FMT(pxFmt.redBits, pxFmt.greenBits, pxFmt.blueBits, pxFmt.alphaBits))
105         {
106                 case PACK_FMT(8,8,8,8):         return GL_RGBA8;
107                 case PACK_FMT(8,8,8,0):         return GL_RGB8;
108                 case PACK_FMT(4,4,4,4):         return GL_RGBA4;
109                 case PACK_FMT(5,5,5,1):         return GL_RGB5_A1;
110                 case PACK_FMT(5,6,5,0):         return GL_RGB565;
111                 default:                                        return GL_NONE;
112         }
113
114 #undef PACK_FMT
115 }
116
117 static deUint32 getCompatibleDepthStencilFormat (const tcu::RenderTarget& renderTargetInfo)
118 {
119         const int       depthBits               = renderTargetInfo.getDepthBits();
120         const int       stencilBits             = renderTargetInfo.getStencilBits();
121         const bool      hasDepth                = depthBits > 0;
122         const bool      hasStencil              = stencilBits > 0;
123
124         if (!hasDepth || !hasStencil || (stencilBits != 8))
125                 return GL_NONE;
126
127         if (depthBits == 32)
128                 return GL_DEPTH32F_STENCIL8;
129         else if (depthBits == 24)
130                 return GL_DEPTH24_STENCIL8;
131         else
132                 return GL_NONE;
133 }
134
135 class InvalidateDefaultFramebufferRenderCase : public FboTestCase
136 {
137 public:
138         InvalidateDefaultFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers, deUint32 fboTarget = GL_FRAMEBUFFER)
139                 : FboTestCase   (context, name, description)
140                 , m_buffers             (buffers)
141                 , m_fboTarget   (fboTarget)
142         {
143         }
144
145         void render (tcu::Surface& dst)
146         {
147                 FlatColorShader         flatShader      (glu::TYPE_FLOAT_VEC4);
148                 vector<deUint32>        attachments     = getDefaultFBDiscardAttachments(m_buffers);
149                 deUint32                        flatShaderID= getCurrentContext()->createProgram(&flatShader);
150
151                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
152                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
153
154                 glEnable                (GL_DEPTH_TEST);
155                 glEnable                (GL_STENCIL_TEST);
156                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
157                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
158
159                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
160                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
161
162                 glInvalidateFramebuffer(m_fboTarget, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);
163
164                 if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0)
165                 {
166                         // Color was not preserved - fill with green.
167                         glDisable(GL_DEPTH_TEST);
168                         glDisable(GL_STENCIL_TEST);
169
170                         flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
171                         sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
172
173                         glEnable(GL_DEPTH_TEST);
174                         glEnable(GL_STENCIL_TEST);
175                 }
176
177                 if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0)
178                 {
179                         // Depth was not preserved.
180                         glDepthFunc(GL_ALWAYS);
181                 }
182
183                 if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0)
184                 {
185                         // Stencil was preserved.
186                         glStencilFunc(GL_EQUAL, 1, 0xff);
187                 }
188
189                 glEnable                (GL_BLEND);
190                 glBlendFunc             (GL_ONE, GL_ONE);
191                 glBlendEquation (GL_FUNC_ADD);
192
193                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
194                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
195
196                 readPixels(dst, 0, 0, getWidth(), getHeight());
197         }
198
199 private:
200         deUint32 m_buffers;
201         deUint32 m_fboTarget;
202 };
203
204 class InvalidateDefaultFramebufferBindCase : public FboTestCase
205 {
206 public:
207         InvalidateDefaultFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
208                 : FboTestCase   (context, name, description)
209                 , m_buffers             (buffers)
210         {
211         }
212
213         void render (tcu::Surface& dst)
214         {
215                 deUint32                        fbo                     = 0;
216                 deUint32                        tex                     = 0;
217                 FlatColorShader         flatShader      (glu::TYPE_FLOAT_VEC4);
218                 Texture2DShader         texShader       (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
219                 GradientShader          gradShader      (glu::TYPE_FLOAT_VEC4);
220                 vector<deUint32>        attachments     = getDefaultFBDiscardAttachments(m_buffers);
221                 deUint32                        flatShaderID= getCurrentContext()->createProgram(&flatShader);
222                 deUint32                        texShaderID = getCurrentContext()->createProgram(&texShader);
223                 deUint32                        gradShaderID= getCurrentContext()->createProgram(&gradShader);
224
225                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
226                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
227
228                 // Create fbo.
229                 glGenFramebuffers               (1, &fbo);
230                 glGenTextures                   (1, &tex);
231                 glBindTexture                   (GL_TEXTURE_2D, tex);
232                 glTexImage2D                    (GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
233                 glTexParameteri                 (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
234                 glBindFramebuffer               (GL_FRAMEBUFFER, fbo);
235                 glFramebufferTexture2D  (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
236                 glBindTexture                   (GL_TEXTURE_2D, 0);
237                 checkFramebufferStatus  (GL_FRAMEBUFFER);
238
239                 glBindFramebuffer               (GL_FRAMEBUFFER, 0);
240
241                 glEnable                (GL_DEPTH_TEST);
242                 glEnable                (GL_STENCIL_TEST);
243                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
244                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
245
246                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
247                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
248
249                 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);
250
251                 // Switch to fbo and render gradient into it.
252                 glDisable                       (GL_DEPTH_TEST);
253                 glDisable                       (GL_STENCIL_TEST);
254                 glBindFramebuffer       (GL_FRAMEBUFFER, fbo);
255
256                 gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
257                 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
258
259                 // Restore default fbo.
260                 glBindFramebuffer       (GL_FRAMEBUFFER, 0);
261
262                 if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0)
263                 {
264                         // Color was not preserved - fill with green.
265                         flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
266                         sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
267                 }
268
269                 if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0)
270                 {
271                         // Depth was not preserved.
272                         glDepthFunc(GL_ALWAYS);
273                 }
274
275                 if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0)
276                 {
277                         // Stencil was preserved.
278                         glStencilFunc(GL_EQUAL, 1, 0xff);
279                 }
280
281                 glEnable                (GL_DEPTH_TEST);
282                 glEnable                (GL_STENCIL_TEST);
283                 glEnable                (GL_BLEND);
284                 glBlendFunc             (GL_ONE, GL_ONE);
285                 glBlendEquation (GL_FUNC_ADD);
286                 glBindTexture   (GL_TEXTURE_2D, tex);
287
288                 texShader.setUniforms(*getCurrentContext(), texShaderID);
289                 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
290
291                 readPixels(dst, 0, 0, getWidth(), getHeight());
292         }
293
294 private:
295         deUint32 m_buffers;
296 };
297
298 class InvalidateDefaultSubFramebufferRenderCase : public FboTestCase
299 {
300 public:
301         InvalidateDefaultSubFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers)
302                 : FboTestCase   (context, name, description)
303                 , m_buffers             (buffers)
304         {
305         }
306
307         void render (tcu::Surface& dst)
308         {
309                 int                                     invalidateX             = getWidth()    / 4;
310                 int                                     invalidateY             = getHeight()   / 4;
311                 int                                     invalidateW             = getWidth()    / 2;
312                 int                                     invalidateH             = getHeight()   / 2;
313                 FlatColorShader         flatShader              (glu::TYPE_FLOAT_VEC4);
314                 vector<deUint32>        attachments             = getDefaultFBDiscardAttachments(m_buffers);
315                 deUint32                        flatShaderID    = getCurrentContext()->createProgram(&flatShader);
316
317                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
318                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
319
320                 glEnable                (GL_DEPTH_TEST);
321                 glEnable                (GL_STENCIL_TEST);
322                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
323                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
324
325                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
326                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
327
328                 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
329
330                 // Clear invalidated buffers.
331                 glClearColor    (0.0f, 1.0f, 0.0f, 1.0f);
332                 glClearStencil  (1);
333                 glScissor               (invalidateX, invalidateY, invalidateW, invalidateH);
334                 glEnable                (GL_SCISSOR_TEST);
335                 glClear                 (m_buffers);
336                 glDisable               (GL_SCISSOR_TEST);
337
338                 glEnable                (GL_BLEND);
339                 glBlendFunc             (GL_ONE, GL_ONE);
340                 glBlendEquation (GL_FUNC_ADD);
341
342                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
343                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
344
345                 readPixels(dst, 0, 0, getWidth(), getHeight());
346         }
347
348 private:
349         deUint32 m_buffers;
350 };
351
352 class InvalidateDefaultSubFramebufferBindCase : public FboTestCase
353 {
354 public:
355         InvalidateDefaultSubFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
356                 : FboTestCase   (context, name, description)
357                 , m_buffers             (buffers)
358         {
359         }
360
361         void render (tcu::Surface& dst)
362         {
363                 deUint32                        fbo                             = 0;
364                 deUint32                        tex                             = 0;
365                 FlatColorShader         flatShader              (glu::TYPE_FLOAT_VEC4);
366                 Texture2DShader         texShader               (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
367                 GradientShader          gradShader              (glu::TYPE_FLOAT_VEC4);
368                 vector<deUint32>        attachments             = getDefaultFBDiscardAttachments(m_buffers);
369                 deUint32                        flatShaderID    = getCurrentContext()->createProgram(&flatShader);
370                 deUint32                        texShaderID             = getCurrentContext()->createProgram(&texShader);
371                 deUint32                        gradShaderID    = getCurrentContext()->createProgram(&gradShader);
372
373                 int                             invalidateX             = getWidth()    / 4;
374                 int                             invalidateY             = getHeight()   / 4;
375                 int                             invalidateW             = getWidth()    / 2;
376                 int                             invalidateH             = getHeight()   / 2;
377
378
379                 flatShader.setColor   (*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
380                 texShader.setUniforms (*getCurrentContext(), texShaderID);
381                 gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
382
383                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
384                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
385
386                 // Create fbo.
387                 glGenFramebuffers               (1, &fbo);
388                 glGenTextures                   (1, &tex);
389                 glBindTexture                   (GL_TEXTURE_2D, tex);
390                 glTexImage2D                    (GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
391                 glTexParameteri                 (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
392                 glBindFramebuffer               (GL_FRAMEBUFFER, fbo);
393                 glFramebufferTexture2D  (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
394                 glBindTexture                   (GL_TEXTURE_2D, 0);
395                 checkFramebufferStatus  (GL_FRAMEBUFFER);
396
397                 glBindFramebuffer               (GL_FRAMEBUFFER, 0);
398
399                 glEnable                (GL_DEPTH_TEST);
400                 glEnable                (GL_STENCIL_TEST);
401                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
402                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
403
404                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
405
406                 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
407
408                 // Switch to fbo and render gradient into it.
409                 glDisable                       (GL_DEPTH_TEST);
410                 glDisable                       (GL_STENCIL_TEST);
411                 glBindFramebuffer       (GL_FRAMEBUFFER, fbo);
412
413                 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
414
415                 // Restore default fbo.
416                 glBindFramebuffer       (GL_FRAMEBUFFER, 0);
417
418                 // Clear invalidated buffers.
419                 glClearColor    (0.0f, 1.0f, 0.0f, 1.0f);
420                 glClearStencil  (1);
421                 glScissor               (invalidateX, invalidateY, invalidateW, invalidateH);
422                 glEnable                (GL_SCISSOR_TEST);
423                 glClear                 (m_buffers);
424                 glDisable               (GL_SCISSOR_TEST);
425
426                 glEnable                (GL_DEPTH_TEST);
427                 glEnable                (GL_STENCIL_TEST);
428                 glEnable                (GL_BLEND);
429                 glBlendFunc             (GL_ONE, GL_ONE);
430                 glBlendEquation (GL_FUNC_ADD);
431                 glBindTexture   (GL_TEXTURE_2D, tex);
432
433                 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
434
435                 readPixels(dst, 0, 0, getWidth(), getHeight());
436         }
437
438 private:
439         deUint32 m_buffers;
440 };
441
442 class InvalidateFboRenderCase : public FboTestCase
443 {
444 public:
445         InvalidateFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
446                 : FboTestCase                   (context, name, description)
447                 , m_colorFmt                    (colorFmt)
448                 , m_depthStencilFmt             (depthStencilFmt)
449                 , m_invalidateBuffers   (invalidateBuffers)
450         {
451         }
452
453 protected:
454         void preCheck (void)
455         {
456                 if (m_colorFmt != GL_NONE)                      checkFormatSupport(m_colorFmt);
457                 if (m_depthStencilFmt != GL_NONE)       checkFormatSupport(m_depthStencilFmt);
458         }
459
460         void render (tcu::Surface& dst)
461         {
462                 tcu::TextureFormat              colorFmt                                = glu::mapGLInternalFormat(m_colorFmt);
463                 tcu::TextureFormat              depthStencilFmt                 = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
464                 tcu::TextureFormatInfo  colorFmtInfo                    = tcu::getTextureFormatInfo(colorFmt);
465                 bool                                    depth                                   = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
466                 bool                                    stencil                                 = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
467                 const tcu::Vec4&                cBias                                   = colorFmtInfo.valueMin;
468                 tcu::Vec4                               cScale                                  = colorFmtInfo.valueMax-colorFmtInfo.valueMin;
469                 deUint32                                fbo                                             = 0;
470                 deUint32                                colorRbo                                = 0;
471                 deUint32                                depthStencilRbo                 = 0;
472                 FlatColorShader                 flatShader                              (glu::TYPE_FLOAT_VEC4);
473                 vector<deUint32>                attachments                             = getFBODiscardAttachments(m_invalidateBuffers);
474                 deUint32                                flatShaderID                    = getCurrentContext()->createProgram(&flatShader);
475
476                 // Create fbo.
477                 glGenRenderbuffers              (1, &colorRbo);
478                 glBindRenderbuffer              (GL_RENDERBUFFER, colorRbo);
479                 glRenderbufferStorage   (GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight());
480
481                 if (m_depthStencilFmt != GL_NONE)
482                 {
483                         glGenRenderbuffers              (1, &depthStencilRbo);
484                         glBindRenderbuffer              (GL_RENDERBUFFER, depthStencilRbo);
485                         glRenderbufferStorage   (GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight());
486                 }
487
488                 glGenFramebuffers                       (1, &fbo);
489                 glBindFramebuffer                       (GL_FRAMEBUFFER, fbo);
490                 glFramebufferRenderbuffer       (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
491
492                 if (depth)
493                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
494
495                 if (stencil)
496                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
497
498                 checkFramebufferStatus          (GL_FRAMEBUFFER);
499
500                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
501                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
502
503                 glEnable                (GL_DEPTH_TEST);
504                 glEnable                (GL_STENCIL_TEST);
505                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
506                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
507
508                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
509                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
510
511                 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);
512
513                 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
514                 {
515                         // Color was not preserved - fill with green.
516                         glDisable(GL_DEPTH_TEST);
517                         glDisable(GL_STENCIL_TEST);
518
519                         flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias);
520                         sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
521
522                         glEnable(GL_DEPTH_TEST);
523                         glEnable(GL_STENCIL_TEST);
524                 }
525
526                 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
527                 {
528                         // Depth was not preserved.
529                         glDepthFunc(GL_ALWAYS);
530                 }
531
532                 if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
533                 {
534                         // Stencil was preserved.
535                         glStencilFunc(GL_EQUAL, 1, 0xff);
536                 }
537
538                 glEnable                (GL_BLEND);
539                 glBlendFunc             (GL_ONE, GL_ONE);
540                 glBlendEquation (GL_FUNC_ADD);
541
542                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
543                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
544
545                 readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
546         }
547
548 private:
549         deUint32        m_colorFmt;
550         deUint32        m_depthStencilFmt;
551         deUint32        m_invalidateBuffers;
552 };
553
554 class InvalidateFboUnbindReadCase : public FboTestCase
555 {
556 public:
557         InvalidateFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
558                 : FboTestCase                   (context, name, description)
559                 , m_colorFmt                    (colorFmt)
560                 , m_depthStencilFmt             (depthStencilFmt)
561                 , m_invalidateBuffers   (invalidateBuffers)
562         {
563                 DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));
564         }
565
566 protected:
567         void preCheck (void)
568         {
569                 if (m_colorFmt != GL_NONE)                      checkFormatSupport(m_colorFmt);
570                 if (m_depthStencilFmt != GL_NONE)       checkFormatSupport(m_depthStencilFmt);
571         }
572
573         void render (tcu::Surface& dst)
574         {
575                 tcu::TextureFormat              colorFmt                                = glu::mapGLInternalFormat(m_colorFmt);
576                 tcu::TextureFormat              depthStencilFmt                 = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
577                 tcu::TextureFormatInfo  colorFmtInfo                    = tcu::getTextureFormatInfo(colorFmt);
578                 bool                                    depth                                   = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
579                 bool                                    stencil                                 = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
580                 deUint32                                fbo                                             = 0;
581                 deUint32                                colorTex                                = 0;
582                 deUint32                                depthStencilTex                 = 0;
583                 GradientShader                  gradShader                              (getFragmentOutputType(colorFmt));
584                 vector<deUint32>                attachments                             = getFBODiscardAttachments(m_invalidateBuffers);
585                 deUint32                                gradShaderID                    = getCurrentContext()->createProgram(&gradShader);
586
587                 // Create fbo.
588                 {
589                         glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt);
590
591                         glGenTextures   (1, &colorTex);
592                         glBindTexture   (GL_TEXTURE_2D, colorTex);
593                         glTexImage2D    (GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
594                         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
595                 }
596
597                 if (m_depthStencilFmt != GL_NONE)
598                 {
599                         glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt);
600
601                         glGenTextures   (1, &depthStencilTex);
602                         glBindTexture   (GL_TEXTURE_2D, depthStencilTex);
603                         glTexImage2D    (GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
604                         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
605                         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
606                 }
607
608                 glGenFramebuffers               (1, &fbo);
609                 glBindFramebuffer               (GL_FRAMEBUFFER, fbo);
610                 glFramebufferTexture2D  (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
611
612                 if (depth)
613                         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
614
615                 if (stencil)
616                         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
617
618                 checkFramebufferStatus          (GL_FRAMEBUFFER);
619
620                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
621                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
622
623                 glEnable                (GL_DEPTH_TEST);
624                 glEnable                (GL_STENCIL_TEST);
625                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
626                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
627
628                 gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
629                 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
630
631                 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]);
632
633                 glBindFramebuffer       (GL_FRAMEBUFFER, 0);
634                 glDisable                       (GL_DEPTH_TEST);
635                 glDisable                       (GL_STENCIL_TEST);
636
637                 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
638                 {
639                         // Render color.
640                         Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4);
641                         deUint32                texShaderID = getCurrentContext()->createProgram(&texShader);
642
643                         texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
644                         texShader.setUniforms(*getCurrentContext(), texShaderID);
645
646                         glBindTexture(GL_TEXTURE_2D, colorTex);
647                         sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
648                 }
649                 else
650                 {
651                         // Render depth.
652                         Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4);
653                         deUint32                texShaderID = getCurrentContext()->createProgram(&texShader);
654
655                         texShader.setUniforms(*getCurrentContext(), texShaderID);
656
657                         glBindTexture(GL_TEXTURE_2D, depthStencilTex);
658                         sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
659                 }
660
661                 readPixels(dst, 0, 0, getWidth(), getHeight());
662         }
663
664 private:
665         deUint32        m_colorFmt;
666         deUint32        m_depthStencilFmt;
667         deUint32        m_invalidateBuffers;
668 };
669
670 class InvalidateFboUnbindBlitCase : public FboTestCase
671 {
672 public:
673         InvalidateFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers)
674                 : FboTestCase                   (context, name, description, numSamples > 0)    // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
675                                                                                                                                                                 //               behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
676                                                                                                                                                                 //               source and destination rectangles must match when multisampling.
677                 , m_colorFmt                    (0)
678                 , m_depthStencilFmt             (0)
679                 , m_numSamples                  (numSamples)
680                 , m_invalidateBuffers   (invalidateBuffers)
681         {
682                 // Figure out formats that are compatible with default framebuffer.
683                 m_colorFmt                      = getCompatibleColorFormat(m_context.getRenderTarget());
684                 m_depthStencilFmt       = getCompatibleDepthStencilFormat(m_context.getRenderTarget());
685         }
686
687 protected:
688         void preCheck (void)
689         {
690                 if (m_context.getRenderTarget().getNumSamples() > 0)
691                         throw tcu::NotSupportedError("Not supported in MSAA config");
692
693                 if (m_colorFmt == GL_NONE)
694                         throw tcu::NotSupportedError("Unsupported color format");
695
696                 if (m_depthStencilFmt == GL_NONE)
697                         throw tcu::NotSupportedError("Unsupported depth/stencil format");
698
699                 checkFormatSupport(m_colorFmt);
700                 checkFormatSupport(m_depthStencilFmt);
701         }
702
703         void render (tcu::Surface& dst)
704         {
705                 // \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most.
706                 IVec2                                   quadSizePixels                  (m_numSamples == 0 ? getWidth() : de::min(128, getWidth()),
707                                                                                                                  m_numSamples == 0 ? getHeight() : de::min(128, getHeight()));
708                 Vec2                                    quadNDCLeftBottomXY             (-1.0f, -1.0f);
709                 Vec2                                    quadNDCSize                             (2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight());
710                 Vec2                                    quadNDCRightTopXY               = quadNDCLeftBottomXY + quadNDCSize;
711                 tcu::TextureFormat              depthStencilFmt                 = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
712                 bool                                    depth                                   = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
713                 bool                                    stencil                                 = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
714                 deUint32                                fbo                                             = 0;
715                 deUint32                                colorRbo                                = 0;
716                 deUint32                                depthStencilRbo                 = 0;
717                 FlatColorShader                 flatShader                              (glu::TYPE_FLOAT_VEC4);
718                 vector<deUint32>                attachments                             = getFBODiscardAttachments(m_invalidateBuffers);
719                 deUint32                                flatShaderID                    = getCurrentContext()->createProgram(&flatShader);
720
721                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
722                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
723
724                 // Create fbo.
725                 glGenRenderbuffers                                      (1, &colorRbo);
726                 glBindRenderbuffer                                      (GL_RENDERBUFFER, colorRbo);
727                 glRenderbufferStorageMultisample        (GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y());
728
729                 if (m_depthStencilFmt != GL_NONE)
730                 {
731                         glGenRenderbuffers                                      (1, &depthStencilRbo);
732                         glBindRenderbuffer                                      (GL_RENDERBUFFER, depthStencilRbo);
733                         glRenderbufferStorageMultisample        (GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y());
734                 }
735
736                 glGenFramebuffers                       (1, &fbo);
737                 glBindFramebuffer                       (GL_FRAMEBUFFER, fbo);
738                 glFramebufferRenderbuffer       (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
739
740                 if (depth)
741                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
742
743                 if (stencil)
744                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
745
746                 checkFramebufferStatus          (GL_FRAMEBUFFER);
747
748                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
749
750                 glEnable                (GL_DEPTH_TEST);
751                 glEnable                (GL_STENCIL_TEST);
752                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
753                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
754
755                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
756                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f));
757
758                 glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]);
759
760                 // Set default framebuffer as draw framebuffer and blit preserved buffers.
761                 glBindFramebuffer       (GL_DRAW_FRAMEBUFFER, 0);
762                 glBlitFramebuffer       (0, 0, quadSizePixels.x(), quadSizePixels.y(),
763                                                          0, 0, quadSizePixels.x(), quadSizePixels.y(),
764                                                          (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST);
765                 glBindFramebuffer       (GL_READ_FRAMEBUFFER, 0);
766
767                 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
768                 {
769                         // Color was not preserved - fill with green.
770                         glDisable(GL_DEPTH_TEST);
771                         glDisable(GL_STENCIL_TEST);
772
773                         flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
774                         sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
775
776                         glEnable(GL_DEPTH_TEST);
777                         glEnable(GL_STENCIL_TEST);
778                 }
779
780                 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
781                 {
782                         // Depth was not preserved.
783                         glDepthFunc(GL_ALWAYS);
784                 }
785
786                 if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
787                 {
788                         // Stencil was preserved.
789                         glStencilFunc(GL_EQUAL, 1, 0xff);
790                 }
791
792                 glEnable                (GL_BLEND);
793                 glBlendFunc             (GL_ONE, GL_ONE);
794                 glBlendEquation (GL_FUNC_ADD);
795
796                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
797                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
798
799                 readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y());
800         }
801
802 private:
803         deUint32        m_colorFmt;
804         deUint32        m_depthStencilFmt;
805         int                     m_numSamples;
806         deUint32        m_invalidateBuffers;
807 };
808
809 class InvalidateSubFboRenderCase : public FboTestCase
810 {
811 public:
812         InvalidateSubFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
813                 : FboTestCase                   (context, name, description)
814                 , m_colorFmt                    (colorFmt)
815                 , m_depthStencilFmt             (depthStencilFmt)
816                 , m_invalidateBuffers   (invalidateBuffers)
817         {
818         }
819
820 protected:
821         void preCheck (void)
822         {
823                 if (m_colorFmt != GL_NONE)                      checkFormatSupport(m_colorFmt);
824                 if (m_depthStencilFmt != GL_NONE)       checkFormatSupport(m_depthStencilFmt);
825         }
826
827         void render (tcu::Surface& dst)
828         {
829                 tcu::TextureFormat              colorFmt                                = glu::mapGLInternalFormat(m_colorFmt);
830                 tcu::TextureFormat              depthStencilFmt                 = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
831                 tcu::TextureFormatInfo  colorFmtInfo                    = tcu::getTextureFormatInfo(colorFmt);
832                 bool                                    depth                                   = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
833                 bool                                    stencil                                 = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
834                 const tcu::Vec4&                cBias                                   = colorFmtInfo.valueMin;
835                 tcu::Vec4                               cScale                                  = colorFmtInfo.valueMax-colorFmtInfo.valueMin;
836                 deUint32                                fbo                                             = 0;
837                 deUint32                                colorRbo                                = 0;
838                 deUint32                                depthStencilRbo                 = 0;
839                 int                                             invalidateX                             = getWidth()    / 4;
840                 int                                             invalidateY                             = getHeight()   / 4;
841                 int                                             invalidateW                             = getWidth()    / 2;
842                 int                                             invalidateH                             = getHeight()   / 2;
843                 FlatColorShader                 flatShader                              (glu::TYPE_FLOAT_VEC4);
844                 vector<deUint32>                attachments                             = getFBODiscardAttachments(m_invalidateBuffers);
845                 deUint32                                flatShaderID                    = getCurrentContext()->createProgram(&flatShader);
846
847                 // Create fbo.
848                 glGenRenderbuffers              (1, &colorRbo);
849                 glBindRenderbuffer              (GL_RENDERBUFFER, colorRbo);
850                 glRenderbufferStorage   (GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight());
851
852                 if (m_depthStencilFmt != GL_NONE)
853                 {
854                         glGenRenderbuffers              (1, &depthStencilRbo);
855                         glBindRenderbuffer              (GL_RENDERBUFFER, depthStencilRbo);
856                         glRenderbufferStorage   (GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight());
857                 }
858
859                 glGenFramebuffers                       (1, &fbo);
860                 glBindFramebuffer                       (GL_FRAMEBUFFER, fbo);
861                 glFramebufferRenderbuffer       (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
862
863                 if (depth)
864                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
865
866                 if (stencil)
867                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
868
869                 checkFramebufferStatus          (GL_FRAMEBUFFER);
870
871                 glClearBufferfv (GL_COLOR, 0, (Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias).getPtr());
872                 glClearBufferfi (GL_DEPTH_STENCIL, 0, 1.0f, 0);
873
874                 glEnable                (GL_DEPTH_TEST);
875                 glEnable                (GL_STENCIL_TEST);
876                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
877                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
878
879                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
880                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
881
882                 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
883
884                 // Clear invalidated buffers.
885                 glScissor       (invalidateX, invalidateY, invalidateW, invalidateH);
886                 glEnable        (GL_SCISSOR_TEST);
887
888                 if (m_invalidateBuffers & GL_COLOR_BUFFER_BIT)
889                         glClearBufferfv(GL_COLOR, 0, (Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias).getPtr());
890
891                 glClear         (m_invalidateBuffers & ~GL_COLOR_BUFFER_BIT);
892                 glDisable       (GL_SCISSOR_TEST);
893
894                 glEnable                (GL_BLEND);
895                 glBlendFunc             (GL_ONE, GL_ONE);
896                 glBlendEquation (GL_FUNC_ADD);
897
898                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
899                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
900
901                 readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
902         }
903
904 private:
905         deUint32        m_colorFmt;
906         deUint32        m_depthStencilFmt;
907         deUint32        m_invalidateBuffers;
908 };
909
910 class InvalidateSubFboUnbindReadCase : public FboTestCase
911 {
912 public:
913         InvalidateSubFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
914                 : FboTestCase                   (context, name, description)
915                 , m_colorFmt                    (colorFmt)
916                 , m_depthStencilFmt             (depthStencilFmt)
917                 , m_invalidateBuffers   (invalidateBuffers)
918         {
919                 DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));
920         }
921
922 protected:
923         void preCheck (void)
924         {
925                 if (m_colorFmt != GL_NONE)                      checkFormatSupport(m_colorFmt);
926                 if (m_depthStencilFmt != GL_NONE)       checkFormatSupport(m_depthStencilFmt);
927         }
928
929         void render (tcu::Surface& dst)
930         {
931                 tcu::TextureFormat              colorFmt                                = glu::mapGLInternalFormat(m_colorFmt);
932                 tcu::TextureFormat              depthStencilFmt                 = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
933                 tcu::TextureFormatInfo  colorFmtInfo                    = tcu::getTextureFormatInfo(colorFmt);
934                 bool                                    depth                                   = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
935                 bool                                    stencil                                 = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
936                 deUint32                                fbo                                             = 0;
937                 deUint32                                colorTex                                = 0;
938                 deUint32                                depthStencilTex                 = 0;
939                 int                                             invalidateX                             = 0;
940                 int                                             invalidateY                             = 0;
941                 int                                             invalidateW                             = getWidth()/2;
942                 int                                             invalidateH                             = getHeight();
943                 int                                             readX                                   = invalidateW;
944                 int                                             readY                                   = 0;
945                 int                                             readW                                   = getWidth()/2;
946                 int                                             readH                                   = getHeight();
947                 GradientShader                  gradShader                              (getFragmentOutputType(colorFmt));
948                 vector<deUint32>                attachments                             = getFBODiscardAttachments(m_invalidateBuffers);
949                 deUint32                                gradShaderID                    = getCurrentContext()->createProgram(&gradShader);
950
951                 // Create fbo.
952                 {
953                         glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt);
954
955                         glGenTextures   (1, &colorTex);
956                         glBindTexture   (GL_TEXTURE_2D, colorTex);
957                         glTexImage2D    (GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
958                         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
959                         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
960                 }
961
962                 if (m_depthStencilFmt != GL_NONE)
963                 {
964                         glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt);
965
966                         glGenTextures   (1, &depthStencilTex);
967                         glBindTexture   (GL_TEXTURE_2D, depthStencilTex);
968                         glTexImage2D    (GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
969                         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
970                         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
971                 }
972
973                 glGenFramebuffers               (1, &fbo);
974                 glBindFramebuffer               (GL_FRAMEBUFFER, fbo);
975                 glFramebufferTexture2D  (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
976
977                 if (depth)
978                         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
979
980                 if (stencil)
981                         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
982
983                 checkFramebufferStatus          (GL_FRAMEBUFFER);
984
985                 clearColorBuffer(colorFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
986                 glClear                 (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
987
988                 glEnable                (GL_DEPTH_TEST);
989                 glEnable                (GL_STENCIL_TEST);
990                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
991                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
992
993                 gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
994                 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
995
996                 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
997
998                 glBindFramebuffer       (GL_FRAMEBUFFER, 0);
999                 glDisable                       (GL_DEPTH_TEST);
1000                 glDisable                       (GL_STENCIL_TEST);
1001
1002                 glClearColor            (0.25f, 0.5f, 0.75f, 1.0f);
1003                 glClear                         (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1004
1005                 // Limit read area using scissor.
1006                 glScissor                       (readX, readY, readW, readH);
1007                 glEnable                        (GL_SCISSOR_TEST);
1008
1009                 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
1010                 {
1011                         // Render color.
1012                         Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4);
1013                         deUint32                texShaderID = getCurrentContext()->createProgram(&texShader);
1014
1015                         texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
1016                         texShader.setUniforms(*getCurrentContext(), texShaderID);
1017
1018                         glBindTexture(GL_TEXTURE_2D, colorTex);
1019                         sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1020                 }
1021                 else
1022                 {
1023                         // Render depth.
1024                         Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4);
1025                         deUint32                texShaderID = getCurrentContext()->createProgram(&texShader);
1026
1027                         texShader.setUniforms(*getCurrentContext(), texShaderID);
1028
1029                         glBindTexture(GL_TEXTURE_2D, depthStencilTex);
1030                         sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1031                 }
1032
1033                 readPixels(dst, 0, 0, getWidth(), getHeight());
1034         }
1035
1036         bool compare (const tcu::Surface& reference, const tcu::Surface& result)
1037         {
1038                 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_colorFmt), tcu::RGBA(12, 12, 12, 12)));
1039
1040                 return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
1041         }
1042
1043 private:
1044         deUint32        m_colorFmt;
1045         deUint32        m_depthStencilFmt;
1046         deUint32        m_invalidateBuffers;
1047 };
1048
1049 class InvalidateSubFboUnbindBlitCase : public FboTestCase
1050 {
1051 public:
1052         InvalidateSubFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers)
1053                 : FboTestCase                   (context, name, description, numSamples > 0)    // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
1054                                                                                                                                                                 //               behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
1055                                                                                                                                                                 //               source and destination rectangles must match when multisampling.
1056                 , m_colorFmt                    (0)
1057                 , m_depthStencilFmt             (0)
1058                 , m_numSamples                  (numSamples)
1059                 , m_invalidateBuffers   (invalidateBuffers)
1060         {
1061                 // Figure out formats that are compatible with default framebuffer.
1062                 m_colorFmt                      = getCompatibleColorFormat(m_context.getRenderTarget());
1063                 m_depthStencilFmt       = getCompatibleDepthStencilFormat(m_context.getRenderTarget());
1064         }
1065
1066 protected:
1067         void preCheck (void)
1068         {
1069                 if (m_context.getRenderTarget().getNumSamples() > 0)
1070                         throw tcu::NotSupportedError("Not supported in MSAA config");
1071
1072                 if (m_colorFmt == GL_NONE)
1073                         throw tcu::NotSupportedError("Unsupported color format");
1074
1075                 if (m_depthStencilFmt == GL_NONE)
1076                         throw tcu::NotSupportedError("Unsupported depth/stencil format");
1077
1078                 checkFormatSupport(m_colorFmt);
1079                 checkFormatSupport(m_depthStencilFmt);
1080         }
1081
1082         void render (tcu::Surface& dst)
1083         {
1084                 // \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most.
1085                 IVec2                                   quadSizePixels                  (m_numSamples == 0 ? getWidth() : de::min(128, getWidth()),
1086                                                                                                                  m_numSamples == 0 ? getHeight() : de::min(128, getHeight()));
1087                 Vec2                                    quadNDCLeftBottomXY             (-1.0f, -1.0f);
1088                 Vec2                                    quadNDCSize                             (2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight());
1089                 Vec2                                    quadNDCRightTopXY               = quadNDCLeftBottomXY + quadNDCSize;
1090                 tcu::TextureFormat              depthStencilFmt                 = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
1091                 bool                                    depth                                   = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
1092                 bool                                    stencil                                 = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
1093                 deUint32                                fbo                                             = 0;
1094                 deUint32                                colorRbo                                = 0;
1095                 deUint32                                depthStencilRbo                 = 0;
1096                 int                                             invalidateX                             = 0;
1097                 int                                             invalidateY                             = 0;
1098                 int                                             invalidateW                             = quadSizePixels.x()/2;
1099                 int                                             invalidateH                             = quadSizePixels.y();
1100                 int                                             blitX0                                  = invalidateW;
1101                 int                                             blitY0                                  = 0;
1102                 int                                             blitX1                                  = blitX0 + quadSizePixels.x()/2;
1103                 int                                             blitY1                                  = blitY0 + quadSizePixels.y();
1104                 FlatColorShader                 flatShader                              (glu::TYPE_FLOAT_VEC4);
1105                 vector<deUint32>                attachments                             = getFBODiscardAttachments(m_invalidateBuffers);
1106                 deUint32                                flatShaderID                    = getCurrentContext()->createProgram(&flatShader);
1107
1108                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
1109                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1110
1111                 // Create fbo.
1112                 glGenRenderbuffers                                      (1, &colorRbo);
1113                 glBindRenderbuffer                                      (GL_RENDERBUFFER, colorRbo);
1114                 glRenderbufferStorageMultisample        (GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y());
1115
1116                 if (m_depthStencilFmt != GL_NONE)
1117                 {
1118                         glGenRenderbuffers                                      (1, &depthStencilRbo);
1119                         glBindRenderbuffer                                      (GL_RENDERBUFFER, depthStencilRbo);
1120                         glRenderbufferStorageMultisample        (GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y());
1121                 }
1122
1123                 glGenFramebuffers                       (1, &fbo);
1124                 glBindFramebuffer                       (GL_FRAMEBUFFER, fbo);
1125                 glFramebufferRenderbuffer       (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
1126
1127                 if (depth)
1128                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
1129
1130                 if (stencil)
1131                         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
1132
1133                 checkFramebufferStatus          (GL_FRAMEBUFFER);
1134
1135                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1136
1137                 glEnable                (GL_DEPTH_TEST);
1138                 glEnable                (GL_STENCIL_TEST);
1139                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
1140                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
1141
1142                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1143                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f));
1144
1145                 glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
1146
1147                 // Set default framebuffer as draw framebuffer and blit preserved buffers.
1148                 glBindFramebuffer       (GL_DRAW_FRAMEBUFFER, 0);
1149                 glBlitFramebuffer       (blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1, (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST);
1150                 glBindFramebuffer       (GL_READ_FRAMEBUFFER, 0);
1151
1152                 if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
1153                 {
1154                         // Color was not preserved - fill with green.
1155                         glDisable(GL_DEPTH_TEST);
1156                         glDisable(GL_STENCIL_TEST);
1157
1158                         flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
1159                         sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
1160
1161                         glEnable(GL_DEPTH_TEST);
1162                         glEnable(GL_STENCIL_TEST);
1163                 }
1164
1165                 if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
1166                 {
1167                         // Depth was not preserved.
1168                         glDepthFunc(GL_ALWAYS);
1169                 }
1170
1171                 if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
1172                 {
1173                         // Stencil was preserved.
1174                         glStencilFunc(GL_EQUAL, 1, 0xff);
1175                 }
1176
1177                 glEnable                (GL_BLEND);
1178                 glBlendFunc             (GL_ONE, GL_ONE);
1179                 glBlendEquation (GL_FUNC_ADD);
1180
1181                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
1182                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
1183
1184                 readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y());
1185         }
1186
1187 private:
1188         deUint32        m_colorFmt;
1189         deUint32        m_depthStencilFmt;
1190         int                     m_numSamples;
1191         deUint32        m_invalidateBuffers;
1192 };
1193
1194 class InvalidateFboTargetCase : public FboTestCase
1195 {
1196 public:
1197         InvalidateFboTargetCase (Context& context, const char* name, const char* description, deUint32 boundTarget, deUint32 invalidateTarget, const deUint32* invalidateAttachments, int numAttachments)
1198                 : FboTestCase                           (context, name, description)
1199                 , m_boundTarget                         (boundTarget)
1200                 , m_invalidateTarget            (invalidateTarget)
1201                 , m_invalidateAttachments       (invalidateAttachments, invalidateAttachments+numAttachments)
1202         {
1203         }
1204
1205 protected:
1206         void render (tcu::Surface& dst)
1207         {
1208                 const deUint32                                  colorFormat                             = GL_RGBA8;
1209                 const deUint32                                  depthStencilFormat              = GL_DEPTH24_STENCIL8;
1210                 const tcu::TextureFormat                colorFmt                                = glu::mapGLInternalFormat(colorFormat);
1211                 const tcu::TextureFormatInfo    colorFmtInfo                    = tcu::getTextureFormatInfo(colorFmt);
1212                 const tcu::Vec4&                                cBias                                   = colorFmtInfo.valueMin;
1213                 const tcu::Vec4                                 cScale                                  = colorFmtInfo.valueMax-colorFmtInfo.valueMin;
1214                 const bool                                              isDiscarded                             = (m_boundTarget == GL_FRAMEBUFFER) ||
1215                                                                                                                                   (m_invalidateTarget == GL_FRAMEBUFFER && m_boundTarget == GL_DRAW_FRAMEBUFFER) ||
1216                                                                                                                                   (m_invalidateTarget == m_boundTarget);
1217                 const bool                                              isColorDiscarded                = isDiscarded && hasAttachment(m_invalidateAttachments, GL_COLOR_ATTACHMENT0);
1218                 const bool                                              isDepthDiscarded                = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_DEPTH_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));
1219                 const bool                                              isStencilDiscarded              = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_STENCIL_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));
1220
1221                 deUint32                                                fbo                                             = 0;
1222                 deUint32                                                colorRbo                                = 0;
1223                 deUint32                                                depthStencilRbo                 = 0;
1224                 FlatColorShader                                 flatShader                              (glu::TYPE_FLOAT_VEC4);
1225                 deUint32                                                flatShaderID                    = getCurrentContext()->createProgram(&flatShader);
1226
1227                 // Create fbo.
1228                 glGenRenderbuffers              (1, &colorRbo);
1229                 glBindRenderbuffer              (GL_RENDERBUFFER, colorRbo);
1230                 glRenderbufferStorage   (GL_RENDERBUFFER, colorFormat, getWidth(), getHeight());
1231
1232                 glGenRenderbuffers              (1, &depthStencilRbo);
1233                 glBindRenderbuffer              (GL_RENDERBUFFER, depthStencilRbo);
1234                 glRenderbufferStorage   (GL_RENDERBUFFER, depthStencilFormat, getWidth(), getHeight());
1235
1236                 glGenFramebuffers                       (1, &fbo);
1237                 glBindFramebuffer                       (GL_FRAMEBUFFER, fbo);
1238                 glFramebufferRenderbuffer       (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
1239                 glFramebufferRenderbuffer       (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
1240                 glFramebufferRenderbuffer       (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
1241
1242                 checkFramebufferStatus          (GL_FRAMEBUFFER);
1243
1244                 glClearColor    (0.0f, 0.0f, 0.0f, 1.0f);
1245                 glClear                 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1246
1247                 glEnable                (GL_DEPTH_TEST);
1248                 glEnable                (GL_STENCIL_TEST);
1249                 glStencilOp             (GL_KEEP, GL_KEEP, GL_REPLACE);
1250                 glStencilFunc   (GL_ALWAYS, 1, 0xff);
1251
1252                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
1253                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
1254
1255                 // Bound FBO to test target and default to other
1256                 if (m_boundTarget != GL_FRAMEBUFFER)
1257                 {
1258                         // Dummy fbo is used as complemeting target (read when discarding draw for example).
1259                         // \note Framework takes care of deleting objects at the end of test case.
1260                         const deUint32  dummyTarget             = m_boundTarget == GL_DRAW_FRAMEBUFFER ?  GL_READ_FRAMEBUFFER : GL_DRAW_FRAMEBUFFER;
1261                         deUint32                dummyFbo                = 0;
1262                         deUint32                dummyColorRbo   = 0;
1263
1264                         glGenRenderbuffers                      (1, &dummyColorRbo);
1265                         glBindRenderbuffer                      (GL_RENDERBUFFER, dummyColorRbo);
1266                         glRenderbufferStorage           (GL_RENDERBUFFER, GL_RGBA8, 64, 64);
1267                         glGenFramebuffers                       (1, &dummyFbo);
1268                         glBindFramebuffer                       (dummyTarget, dummyFbo);
1269                         glFramebufferRenderbuffer       (dummyTarget, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, dummyColorRbo);
1270
1271                         glBindFramebuffer                       (m_boundTarget, fbo);
1272                 }
1273
1274                 glInvalidateFramebuffer(m_invalidateTarget, (int)m_invalidateAttachments.size(), m_invalidateAttachments.empty() ? DE_NULL : &m_invalidateAttachments[0]);
1275
1276                 if (m_boundTarget != GL_FRAMEBUFFER)
1277                         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1278
1279                 if (isColorDiscarded)
1280                 {
1281                         // Color was not preserved - fill with green.
1282                         glDisable(GL_DEPTH_TEST);
1283                         glDisable(GL_STENCIL_TEST);
1284
1285                         flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias);
1286                         sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1287
1288                         glEnable(GL_DEPTH_TEST);
1289                         glEnable(GL_STENCIL_TEST);
1290                 }
1291
1292                 if (isDepthDiscarded)
1293                 {
1294                         // Depth was not preserved.
1295                         glDepthFunc(GL_ALWAYS);
1296                 }
1297
1298                 if (!isStencilDiscarded)
1299                 {
1300                         // Stencil was preserved.
1301                         glStencilFunc(GL_EQUAL, 1, 0xff);
1302                 }
1303
1304                 glEnable                (GL_BLEND);
1305                 glBlendFunc             (GL_ONE, GL_ONE);
1306                 glBlendEquation (GL_FUNC_ADD);
1307
1308                 flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
1309                 sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1310
1311                 readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
1312         }
1313
1314 private:
1315         deUint32                                m_boundTarget;
1316         deUint32                                m_invalidateTarget;
1317         std::vector<deUint32>   m_invalidateAttachments;
1318 };
1319
1320 FboInvalidateTests::FboInvalidateTests (Context& context)
1321         : TestCaseGroup(context, "invalidate", "Framebuffer invalidate tests")
1322 {
1323 }
1324
1325 FboInvalidateTests::~FboInvalidateTests (void)
1326 {
1327 }
1328
1329 void FboInvalidateTests::init (void)
1330 {
1331         // invalidate.default.
1332         {
1333                 tcu::TestCaseGroup* defaultFbGroup = new tcu::TestCaseGroup(m_testCtx, "default", "Default framebuffer invalidate tests");
1334                 addChild(defaultFbGroup);
1335
1336                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "render_none",                          "Invalidating no framebuffers (ref)",                                           0));
1337                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "render_color",                         "Rendering after invalidating colorbuffer",                                     GL_COLOR_BUFFER_BIT));
1338                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "render_depth",                         "Rendering after invalidating depthbuffer",                                     GL_DEPTH_BUFFER_BIT));
1339                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "render_stencil",                       "Rendering after invalidating stencilbuffer",                           GL_STENCIL_BUFFER_BIT));
1340                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "render_depth_stencil",         "Rendering after invalidating depth- and stencilbuffers",       GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1341                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "render_all",                           "Rendering after invalidating all buffers",                                     GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1342
1343                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase               (m_context,     "bind_color",                           "Binding fbo after invalidating colorbuffer",                           GL_COLOR_BUFFER_BIT));
1344                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase               (m_context,     "bind_depth",                           "Binding fbo after invalidating depthbuffer",                           GL_DEPTH_BUFFER_BIT));
1345                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase               (m_context,     "bind_stencil",                         "Binding fbo after invalidating stencilbuffer",                         GL_STENCIL_BUFFER_BIT));
1346                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase               (m_context,     "bind_depth_stencil",           "Binding fbo after invalidating depth- and stencilbuffers",     GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1347                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase               (m_context,     "bind_all",                                     "Binding fbo after invalidating all buffers",                           GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1348
1349                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase  (m_context,     "sub_render_color",                     "Rendering after invalidating colorbuffer",                                     GL_COLOR_BUFFER_BIT));
1350                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase  (m_context,     "sub_render_depth",                     "Rendering after invalidating depthbuffer",                                     GL_DEPTH_BUFFER_BIT));
1351                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase  (m_context,     "sub_render_stencil",           "Rendering after invalidating stencilbuffer",                           GL_STENCIL_BUFFER_BIT));
1352                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase  (m_context,     "sub_render_depth_stencil",     "Rendering after invalidating depth- and stencilbuffers",       GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1353                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase  (m_context,     "sub_render_all",                       "Rendering after invalidating all buffers",                                     GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1354
1355                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase    (m_context,     "sub_bind_color",                       "Binding fbo after invalidating colorbuffer",                           GL_COLOR_BUFFER_BIT));
1356                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase    (m_context,     "sub_bind_depth",                       "Binding fbo after invalidating depthbuffer",                           GL_DEPTH_BUFFER_BIT));
1357                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase    (m_context,     "sub_bind_stencil",                     "Binding fbo after invalidating stencilbuffer",                         GL_STENCIL_BUFFER_BIT));
1358                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase    (m_context,     "sub_bind_depth_stencil",       "Binding fbo after invalidating depth- and stencilbuffers",     GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1359                 defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase    (m_context,     "sub_bind_all",                         "Binding fbo after invalidating all buffers",                           GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1360
1361                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "draw_framebuffer_color",       "Invalidating GL_COLOR in GL_DRAW_FRAMEBUFFER",                         GL_COLOR_BUFFER_BIT,                                                                                    GL_DRAW_FRAMEBUFFER));
1362                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "draw_framebuffer_all",         "Invalidating all in GL_DRAW_FRAMEBUFFER",                                      GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT,  GL_DRAW_FRAMEBUFFER));
1363                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "read_framebuffer_color",       "Invalidating GL_COLOR in GL_READ_FRAMEBUFFER",                         GL_COLOR_BUFFER_BIT,                                                                                    GL_READ_FRAMEBUFFER));
1364                 defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase             (m_context,     "read_framebuffer_all",         "Invalidating all in GL_READ_FRAMEBUFFER",                                      GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT,  GL_READ_FRAMEBUFFER));
1365         }
1366
1367         // invalidate.whole.
1368         {
1369                 tcu::TestCaseGroup* wholeFboGroup = new tcu::TestCaseGroup(m_testCtx, "whole", "Invalidating whole framebuffer object");
1370                 addChild(wholeFboGroup);
1371
1372                 wholeFboGroup->addChild(new InvalidateFboRenderCase             (m_context, "render_none",                                              "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    0));
1373                 wholeFboGroup->addChild(new InvalidateFboRenderCase             (m_context, "render_color",                                             "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT));
1374                 wholeFboGroup->addChild(new InvalidateFboRenderCase             (m_context, "render_depth",                                             "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT));
1375                 wholeFboGroup->addChild(new InvalidateFboRenderCase             (m_context, "render_stencil",                                   "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_STENCIL_BUFFER_BIT));
1376                 wholeFboGroup->addChild(new InvalidateFboRenderCase             (m_context, "render_depth_stencil",                             "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1377                 wholeFboGroup->addChild(new InvalidateFboRenderCase             (m_context, "render_all",                                               "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1378
1379                 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_color",                                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT));
1380                 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_depth",                                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT));
1381                 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_stencil",                              "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_STENCIL_BUFFER_BIT));
1382                 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_depth_stencil",                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1383                 wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_color_stencil",                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1384
1385                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_color",                                "",             0,      GL_COLOR_BUFFER_BIT));
1386                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_depth",                                "",             0,      GL_DEPTH_BUFFER_BIT));
1387                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_stencil",                              "",             0,      GL_STENCIL_BUFFER_BIT));
1388                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_depth_stencil",                "",             0,      GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1389
1390                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_color",                   "",             4,      GL_COLOR_BUFFER_BIT));
1391                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_depth",                   "",             4,      GL_DEPTH_BUFFER_BIT));
1392                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_stencil",                 "",             4,      GL_STENCIL_BUFFER_BIT));
1393                 wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_depth_stencil",   "",             4,      GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1394         }
1395
1396         // invalidate.sub.
1397         {
1398                 tcu::TestCaseGroup* subFboGroup = new tcu::TestCaseGroup(m_testCtx, "sub", "Invalidating subsection of framebuffer object");
1399                 addChild(subFboGroup);
1400
1401                 subFboGroup->addChild(new InvalidateSubFboRenderCase    (m_context, "render_none",                                              "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    0));
1402                 subFboGroup->addChild(new InvalidateSubFboRenderCase    (m_context, "render_color",                                             "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT));
1403                 subFboGroup->addChild(new InvalidateSubFboRenderCase    (m_context, "render_depth",                                             "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT));
1404                 subFboGroup->addChild(new InvalidateSubFboRenderCase    (m_context, "render_stencil",                                   "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_STENCIL_BUFFER_BIT));
1405                 subFboGroup->addChild(new InvalidateSubFboRenderCase    (m_context, "render_depth_stencil",                             "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1406                 subFboGroup->addChild(new InvalidateSubFboRenderCase    (m_context, "render_all",                                               "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1407
1408                 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color",                                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT));
1409                 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth",                                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT));
1410                 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_stencil",                              "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_STENCIL_BUFFER_BIT));
1411                 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth_stencil",                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1412                 subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color_stencil",                "",             GL_RGBA8,               GL_DEPTH24_STENCIL8,    GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1413
1414                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_color",                                "",             0,      GL_COLOR_BUFFER_BIT));
1415                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth",                                "",             0,      GL_DEPTH_BUFFER_BIT));
1416                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_stencil",                              "",             0,      GL_STENCIL_BUFFER_BIT));
1417                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth_stencil",                "",             0,      GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1418
1419                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_color",                   "",             4,      GL_COLOR_BUFFER_BIT));
1420                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth",                   "",             4,      GL_DEPTH_BUFFER_BIT));
1421                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_stencil",                 "",             4,      GL_STENCIL_BUFFER_BIT));
1422                 subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth_stencil",   "",             4,      GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1423         }
1424
1425         // invalidate.format.
1426         {
1427                 tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Invalidating framebuffers with selected formats");
1428                 addChild(formatGroup);
1429
1430                 // Color buffer formats.
1431                 static const deUint32 colorFormats[] =
1432                 {
1433                         // RGBA formats
1434                         GL_RGBA32I,
1435                         GL_RGBA32UI,
1436                         GL_RGBA16I,
1437                         GL_RGBA16UI,
1438                         GL_RGBA8,
1439                         GL_RGBA8I,
1440                         GL_RGBA8UI,
1441                         GL_SRGB8_ALPHA8,
1442                         GL_RGB10_A2,
1443                         GL_RGB10_A2UI,
1444                         GL_RGBA4,
1445                         GL_RGB5_A1,
1446
1447                         // RGB formats
1448                         GL_RGB8,
1449                         GL_RGB565,
1450
1451                         // RG formats
1452                         GL_RG32I,
1453                         GL_RG32UI,
1454                         GL_RG16I,
1455                         GL_RG16UI,
1456                         GL_RG8,
1457                         GL_RG8I,
1458                         GL_RG8UI,
1459
1460                         // R formats
1461                         GL_R32I,
1462                         GL_R32UI,
1463                         GL_R16I,
1464                         GL_R16UI,
1465                         GL_R8,
1466                         GL_R8I,
1467                         GL_R8UI,
1468
1469                         // GL_EXT_color_buffer_float
1470                         GL_RGBA32F,
1471                         GL_RGBA16F,
1472                         GL_R11F_G11F_B10F,
1473                         GL_RG32F,
1474                         GL_RG16F,
1475                         GL_R32F,
1476                         GL_R16F
1477                 };
1478
1479                 // Depth/stencilbuffer formats.
1480                 static const deUint32 depthStencilFormats[] =
1481                 {
1482                         GL_DEPTH_COMPONENT32F,
1483                         GL_DEPTH_COMPONENT24,
1484                         GL_DEPTH_COMPONENT16,
1485                         GL_DEPTH32F_STENCIL8,
1486                         GL_DEPTH24_STENCIL8,
1487                         GL_STENCIL_INDEX8
1488                 };
1489
1490                 // Colorbuffer tests use invalidate, unbind, read test.
1491                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
1492                         formatGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], GL_NONE, GL_COLOR_BUFFER_BIT));
1493
1494                 // Depth/stencilbuffer tests use invalidate, render test.
1495                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
1496                         formatGroup->addChild(new InvalidateSubFboRenderCase(m_context, getFormatName(depthStencilFormats[ndx]), "", GL_RGBA8, depthStencilFormats[ndx], GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
1497         }
1498
1499         // invalidate.target
1500         {
1501                 tcu::TestCaseGroup* targetGroup = new tcu::TestCaseGroup(m_testCtx, "target", "Invalidate target");
1502                 addChild(targetGroup);
1503
1504                 static const struct
1505                 {
1506                         const char*             name;
1507                         deUint32                invalidateTarget;
1508                         deUint32                boundTarget;
1509                 } s_targetCases[] =
1510                 {
1511                         { "framebuffer_framebuffer",                    GL_FRAMEBUFFER,                 GL_FRAMEBUFFER          },
1512                         { "framebuffer_read_framebuffer",               GL_FRAMEBUFFER,                 GL_READ_FRAMEBUFFER },
1513                         { "framebuffer_draw_framebuffer",               GL_FRAMEBUFFER,                 GL_DRAW_FRAMEBUFFER },
1514                         { "read_framebuffer_framebuffer",               GL_READ_FRAMEBUFFER,    GL_FRAMEBUFFER          },
1515                         { "read_framebuffer_read_framebuffer",  GL_READ_FRAMEBUFFER,    GL_READ_FRAMEBUFFER },
1516                         { "read_framebuffer_draw_framebuffer",  GL_READ_FRAMEBUFFER,    GL_DRAW_FRAMEBUFFER },
1517                         { "draw_framebuffer_framebuffer",               GL_DRAW_FRAMEBUFFER,    GL_FRAMEBUFFER          },
1518                         { "draw_framebuffer_read_framebuffer",  GL_DRAW_FRAMEBUFFER,    GL_READ_FRAMEBUFFER },
1519                         { "draw_framebuffer_draw_framebuffer",  GL_DRAW_FRAMEBUFFER,    GL_DRAW_FRAMEBUFFER },
1520                 };
1521
1522                 static const deUint32 colorAttachment[]                 = { GL_COLOR_ATTACHMENT0 };
1523                 static const deUint32 depthStencilAttachment[]  = { GL_DEPTH_STENCIL_ATTACHMENT };
1524                 static const deUint32 allAttachments[]                  = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
1525
1526                 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_targetCases); caseNdx++)
1527                 {
1528                         const std::string       baseName                = s_targetCases[caseNdx].name;
1529                         const deUint32          invalidateT             = s_targetCases[caseNdx].invalidateTarget;
1530                         const deUint32          boundT                  = s_targetCases[caseNdx].boundTarget;
1531
1532                         targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_color").c_str(),                     "",     boundT, invalidateT, &colorAttachment[0],                       DE_LENGTH_OF_ARRAY(colorAttachment)));
1533                         targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_depth_stencil").c_str(),     "",     boundT, invalidateT, &depthStencilAttachment[0],        DE_LENGTH_OF_ARRAY(depthStencilAttachment)));
1534                         targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_all").c_str(),                       "",     boundT, invalidateT, &allAttachments[0],                        DE_LENGTH_OF_ARRAY(allAttachments)));
1535                 }
1536         }
1537 }
1538
1539 } // Functional
1540 } // gles3
1541 } // deqp