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
getDefaultFBDiscardAttachments(deUint32 discardBufferBits)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
getFBODiscardAttachments(deUint32 discardBufferBits)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
hasAttachment(const std::vector<deUint32> & attachmentList,deUint32 attachment)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
getCompatibleColorFormat(const tcu::RenderTarget & renderTargetInfo)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
getCompatibleDepthStencilFormat(const tcu::RenderTarget & renderTargetInfo)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:
InvalidateDefaultFramebufferRenderCase(Context & context,const char * name,const char * description,deUint32 buffers,deUint32 fboTarget=GL_FRAMEBUFFER)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
render(tcu::Surface & dst)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:
InvalidateDefaultFramebufferBindCase(Context & context,const char * name,const char * description,deUint32 buffers)207 InvalidateDefaultFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
208 : FboTestCase (context, name, description)
209 , m_buffers (buffers)
210 {
211 }
212
render(tcu::Surface & dst)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:
InvalidateDefaultSubFramebufferRenderCase(Context & context,const char * name,const char * description,deUint32 buffers)301 InvalidateDefaultSubFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers)
302 : FboTestCase (context, name, description)
303 , m_buffers (buffers)
304 {
305 }
306
render(tcu::Surface & dst)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:
InvalidateDefaultSubFramebufferBindCase(Context & context,const char * name,const char * description,deUint32 buffers)355 InvalidateDefaultSubFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
356 : FboTestCase (context, name, description)
357 , m_buffers (buffers)
358 {
359 }
360
render(tcu::Surface & dst)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:
InvalidateFboRenderCase(Context & context,const char * name,const char * description,deUint32 colorFmt,deUint32 depthStencilFmt,deUint32 invalidateBuffers)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:
preCheck(void)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
render(tcu::Surface & dst)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:
InvalidateFboUnbindReadCase(Context & context,const char * name,const char * description,deUint32 colorFmt,deUint32 depthStencilFmt,deUint32 invalidateBuffers)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:
preCheck(void)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
render(tcu::Surface & dst)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:
InvalidateFboUnbindBlitCase(Context & context,const char * name,const char * description,int numSamples,deUint32 invalidateBuffers)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:
preCheck(void)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
render(tcu::Surface & dst)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:
InvalidateSubFboRenderCase(Context & context,const char * name,const char * description,deUint32 colorFmt,deUint32 depthStencilFmt,deUint32 invalidateBuffers)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:
preCheck(void)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
render(tcu::Surface & dst)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:
InvalidateSubFboUnbindReadCase(Context & context,const char * name,const char * description,deUint32 colorFmt,deUint32 depthStencilFmt,deUint32 invalidateBuffers)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:
preCheck(void)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
render(tcu::Surface & dst)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
compare(const tcu::Surface & reference,const tcu::Surface & result)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:
InvalidateSubFboUnbindBlitCase(Context & context,const char * name,const char * description,int numSamples,deUint32 invalidateBuffers)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:
preCheck(void)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
render(tcu::Surface & dst)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:
InvalidateFboTargetCase(Context & context,const char * name,const char * description,deUint32 boundTarget,deUint32 invalidateTarget,const deUint32 * invalidateAttachments,int numAttachments)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:
render(tcu::Surface & dst)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
FboInvalidateTests(Context & context)1320 FboInvalidateTests::FboInvalidateTests (Context& context)
1321 : TestCaseGroup(context, "invalidate", "Framebuffer invalidate tests")
1322 {
1323 }
1324
~FboInvalidateTests(void)1325 FboInvalidateTests::~FboInvalidateTests (void)
1326 {
1327 }
1328
init(void)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
1542