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