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 Framebuffer Object Tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fFboRenderTest.hpp"
25 #include "sglrContextUtil.hpp"
26 #include "sglrGLContext.hpp"
27 #include "sglrReferenceContext.hpp"
28 #include "es3fFboTestUtil.hpp"
29 #include "tcuSurface.hpp"
30 #include "tcuImageCompare.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuVectorUtil.hpp"
33 #include "tcuRenderTarget.hpp"
34 #include "gluPixelTransfer.hpp"
35 #include "gluTextureUtil.hpp"
36 #include "gluStrUtil.hpp"
37 #include "deRandom.h"
38 #include "deString.h"
39 #include "glwDefs.hpp"
40 #include "glwEnums.hpp"
41
42 #include <sstream>
43
44 using std::vector;
45 using std::string;
46 using tcu::TestLog;
47 using tcu::Vec2;
48 using tcu::Vec3;
49 using tcu::Vec4;
50 using tcu::IVec2;
51 using tcu::IVec3;
52 using tcu::IVec4;
53 using tcu::RGBA;
54 using tcu::Surface;
55
56 namespace deqp
57 {
58 namespace gles3
59 {
60 namespace Functional
61 {
62
63 using glw::GLenum;
64 using namespace FboTestUtil;
65
66 class FboConfig
67 {
68 public:
FboConfig(deUint32 buffers_,deUint32 colorType_,deUint32 colorFormat_,deUint32 depthStencilType_,deUint32 depthStencilFormat_,int width_=0,int height_=0,int samples_=0)69 FboConfig (deUint32 buffers_, deUint32 colorType_, deUint32 colorFormat_, deUint32 depthStencilType_, deUint32 depthStencilFormat_, int width_ = 0, int height_ = 0, int samples_ = 0)
70 : buffers (buffers_)
71 , colorType (colorType_)
72 , colorFormat (colorFormat_)
73 , depthStencilType (depthStencilType_)
74 , depthStencilFormat (depthStencilFormat_)
75 , width (width_)
76 , height (height_)
77 , samples (samples_)
78 {
79 }
80
FboConfig(void)81 FboConfig (void)
82 : buffers (0)
83 , colorType (GL_NONE)
84 , colorFormat (GL_NONE)
85 , depthStencilType (GL_NONE)
86 , depthStencilFormat (GL_NONE)
87 , width (0)
88 , height (0)
89 , samples (0)
90 {
91 }
92
93 std::string getName (void) const;
94
95 deUint32 buffers; //!< Buffer bit mask (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|...)
96
97 GLenum colorType; //!< GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER
98 GLenum colorFormat; //!< Internal format for color buffer texture or renderbuffer
99
100 GLenum depthStencilType;
101 GLenum depthStencilFormat;
102
103 int width;
104 int height;
105 int samples;
106 };
107
getTypeName(GLenum type)108 static const char* getTypeName (GLenum type)
109 {
110 switch (type)
111 {
112 case GL_TEXTURE_2D: return "tex2d";
113 case GL_RENDERBUFFER: return "rbo";
114 default:
115 TCU_FAIL("Unknown type");
116 }
117 }
118
getName(void) const119 std::string FboConfig::getName (void) const
120 {
121 std::ostringstream name;
122
123 DE_ASSERT(buffers & GL_COLOR_BUFFER_BIT);
124 name << getTypeName(colorType) << "_" << getFormatName(colorFormat);
125
126 if (buffers & GL_DEPTH_BUFFER_BIT)
127 name << "_depth";
128 if (buffers & GL_STENCIL_BUFFER_BIT)
129 name << "_stencil";
130
131 if (buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))
132 name << "_" << getTypeName(depthStencilType) << "_" << getFormatName(depthStencilFormat);
133
134 return name.str();
135 }
136
137 class Framebuffer
138 {
139 public:
140 Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo = 0, deUint32 colorBuffer = 0, deUint32 depthStencilBuffer = 0);
141 ~Framebuffer (void);
142
getConfig(void) const143 const FboConfig& getConfig (void) const { return m_config; }
getFramebuffer(void) const144 deUint32 getFramebuffer (void) const { return m_framebuffer; }
getColorBuffer(void) const145 deUint32 getColorBuffer (void) const { return m_colorBuffer; }
getDepthStencilBuffer(void) const146 deUint32 getDepthStencilBuffer (void) const { return m_depthStencilBuffer; }
147
148 void checkCompleteness (void);
149
150 private:
151 deUint32 createTex2D (deUint32 name, GLenum format, int width, int height);
152 deUint32 createRbo (deUint32 name, GLenum format, int width, int height);
153 void destroyBuffer (deUint32 name, GLenum type);
154
155 FboConfig m_config;
156 sglr::Context& m_context;
157 deUint32 m_framebuffer;
158 deUint32 m_colorBuffer;
159 deUint32 m_depthStencilBuffer;
160 };
161
getEnablingExtensions(deUint32 format)162 static std::vector<std::string> getEnablingExtensions (deUint32 format)
163 {
164 std::vector<std::string> out;
165
166 switch (format)
167 {
168 case GL_RGB16F:
169 out.push_back("GL_EXT_color_buffer_half_float");
170 break;
171
172 case GL_RGBA16F:
173 case GL_RG16F:
174 case GL_R16F:
175 out.push_back("GL_EXT_color_buffer_half_float");
176
177 case GL_RGBA32F:
178 case GL_RGB32F:
179 case GL_R11F_G11F_B10F:
180 case GL_RG32F:
181 case GL_R32F:
182 out.push_back("GL_EXT_color_buffer_float");
183
184 default:
185 break;
186 }
187
188 return out;
189 }
190
isExtensionSupported(sglr::Context & context,const char * name)191 static bool isExtensionSupported (sglr::Context& context, const char* name)
192 {
193 std::istringstream extensions(context.getString(GL_EXTENSIONS));
194 std::string extension;
195
196 while (std::getline(extensions, extension, ' '))
197 {
198 if (extension == name)
199 return true;
200 }
201
202 return false;
203 }
204
isAnyExtensionSupported(sglr::Context & context,const std::vector<std::string> & requiredExts)205 static bool isAnyExtensionSupported (sglr::Context& context, const std::vector<std::string>& requiredExts)
206 {
207 if (requiredExts.empty())
208 return true;
209
210 for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
211 {
212 const std::string& extension = *iter;
213
214 if (isExtensionSupported(context, extension.c_str()))
215 return true;
216 }
217
218 return false;
219 }
220
221 template<typename T>
join(const std::vector<T> & list,const std::string & sep)222 static std::string join (const std::vector<T>& list, const std::string& sep)
223 {
224 std::ostringstream out;
225
226 for (typename std::vector<T>::const_iterator iter = list.begin(); iter != list.end(); iter++)
227 {
228 if (iter != list.begin())
229 out << sep;
230 out << *iter;
231 }
232
233 return out.str();
234 }
235
checkColorFormatSupport(sglr::Context & context,deUint32 sizedFormat)236 static void checkColorFormatSupport (sglr::Context& context, deUint32 sizedFormat)
237 {
238 const std::vector<std::string> requiredExts = getEnablingExtensions(sizedFormat);
239
240 if (!isAnyExtensionSupported(context, requiredExts))
241 {
242 std::string errMsg = "Format not supported, requires "
243 + ((requiredExts.size() == 1) ? requiredExts[0] : " one of the following: " + join(requiredExts, ", "));
244
245 throw tcu::NotSupportedError(errMsg);
246 }
247 }
248
Framebuffer(sglr::Context & context,const FboConfig & config,int width,int height,deUint32 fbo,deUint32 colorBufferName,deUint32 depthStencilBufferName)249 Framebuffer::Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo, deUint32 colorBufferName, deUint32 depthStencilBufferName)
250 : m_config (config)
251 , m_context (context)
252 , m_framebuffer (fbo)
253 , m_colorBuffer (0)
254 , m_depthStencilBuffer (0)
255 {
256 // Verify that color format is supported
257 checkColorFormatSupport(context, config.colorFormat);
258
259 if (m_framebuffer == 0)
260 context.genFramebuffers(1, &m_framebuffer);
261 context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
262
263 if (m_config.buffers & (GL_COLOR_BUFFER_BIT))
264 {
265 switch (m_config.colorType)
266 {
267 case GL_TEXTURE_2D:
268 m_colorBuffer = createTex2D(colorBufferName, m_config.colorFormat, width, height);
269 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
270 break;
271
272 case GL_RENDERBUFFER:
273 m_colorBuffer = createRbo(colorBufferName, m_config.colorFormat, width, height);
274 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorBuffer);
275 break;
276
277 default:
278 TCU_FAIL("Unsupported type");
279 }
280 }
281
282 if (m_config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))
283 {
284 switch (m_config.depthStencilType)
285 {
286 case GL_TEXTURE_2D: m_depthStencilBuffer = createTex2D(depthStencilBufferName, m_config.depthStencilFormat, width, height); break;
287 case GL_RENDERBUFFER: m_depthStencilBuffer = createRbo(depthStencilBufferName, m_config.depthStencilFormat, width, height); break;
288 default:
289 TCU_FAIL("Unsupported type");
290 }
291 }
292
293 for (int ndx = 0; ndx < 2; ndx++)
294 {
295 deUint32 bit = ndx ? GL_STENCIL_BUFFER_BIT : GL_DEPTH_BUFFER_BIT;
296 deUint32 point = ndx ? GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
297
298 if ((m_config.buffers & bit) == 0)
299 continue; /* Not used. */
300
301 switch (m_config.depthStencilType)
302 {
303 case GL_TEXTURE_2D: context.framebufferTexture2D(GL_FRAMEBUFFER, point, GL_TEXTURE_2D, m_depthStencilBuffer, 0); break;
304 case GL_RENDERBUFFER: context.framebufferRenderbuffer(GL_FRAMEBUFFER, point, GL_RENDERBUFFER, m_depthStencilBuffer); break;
305 default:
306 DE_ASSERT(false);
307 }
308 }
309
310 GLenum err = m_context.getError();
311 if (err != GL_NO_ERROR)
312 throw glu::Error(err, glu::getErrorStr(err).toString().c_str(), "", __FILE__, __LINE__);
313
314 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
315 }
316
~Framebuffer(void)317 Framebuffer::~Framebuffer (void)
318 {
319 m_context.deleteFramebuffers(1, &m_framebuffer);
320 destroyBuffer(m_colorBuffer, m_config.colorType);
321 destroyBuffer(m_depthStencilBuffer, m_config.depthStencilType);
322 }
323
checkCompleteness(void)324 void Framebuffer::checkCompleteness (void)
325 {
326 m_context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
327 GLenum status = m_context.checkFramebufferStatus(GL_FRAMEBUFFER);
328 m_context.bindFramebuffer(GL_FRAMEBUFFER, 0);
329 if (status != GL_FRAMEBUFFER_COMPLETE)
330 throw FboIncompleteException(status, __FILE__, __LINE__);
331 }
332
createTex2D(deUint32 name,GLenum format,int width,int height)333 deUint32 Framebuffer::createTex2D (deUint32 name, GLenum format, int width, int height)
334 {
335 if (name == 0)
336 m_context.genTextures(1, &name);
337
338 m_context.bindTexture(GL_TEXTURE_2D, name);
339 m_context.texImage2D(GL_TEXTURE_2D, 0, format, width, height);
340
341 if (!deIsPowerOfTwo32(width) || !deIsPowerOfTwo32(height))
342 {
343 // Set wrap mode to clamp for NPOT FBOs
344 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
345 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
346 }
347
348 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
349 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
350
351 return name;
352 }
353
createRbo(deUint32 name,GLenum format,int width,int height)354 deUint32 Framebuffer::createRbo (deUint32 name, GLenum format, int width, int height)
355 {
356 if (name == 0)
357 m_context.genRenderbuffers(1, &name);
358
359 m_context.bindRenderbuffer(GL_RENDERBUFFER, name);
360 m_context.renderbufferStorage(GL_RENDERBUFFER, format, width, height);
361
362 return name;
363 }
364
destroyBuffer(deUint32 name,GLenum type)365 void Framebuffer::destroyBuffer (deUint32 name, GLenum type)
366 {
367 if (type == GL_TEXTURE_2D || type == GL_TEXTURE_CUBE_MAP)
368 m_context.deleteTextures(1, &name);
369 else if (type == GL_RENDERBUFFER)
370 m_context.deleteRenderbuffers(1, &name);
371 else
372 DE_ASSERT(type == GL_NONE);
373 }
374
createMetaballsTex2D(sglr::Context & context,deUint32 name,GLenum format,GLenum dataType,int width,int height)375 static void createMetaballsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height)
376 {
377 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType);
378 tcu::TextureLevel level (texFormat, width, height);
379
380 tcu::fillWithMetaballs(level.getAccess(), 5, name ^ width ^ height);
381
382 context.bindTexture(GL_TEXTURE_2D, name);
383 context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr());
384 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
385 }
386
createQuadsTex2D(sglr::Context & context,deUint32 name,GLenum format,GLenum dataType,int width,int height)387 static void createQuadsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height)
388 {
389 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType);
390 tcu::TextureLevel level (texFormat, width, height);
391
392 tcu::fillWithRGBAQuads(level.getAccess());
393
394 context.bindTexture(GL_TEXTURE_2D, name);
395 context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr());
396 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
397 }
398
399 class FboRenderCase : public TestCase
400 {
401 public:
402 FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config);
~FboRenderCase(void)403 virtual ~FboRenderCase (void) {}
404
405 virtual IterateResult iterate (void);
406 virtual void render (sglr::Context& fboContext, Surface& dst) = DE_NULL;
407
408 bool compare (const tcu::Surface& reference, const tcu::Surface& result);
409
410 protected:
411 const FboConfig m_config;
412 };
413
FboRenderCase(Context & context,const char * name,const char * description,const FboConfig & config)414 FboRenderCase::FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config)
415 : TestCase (context, name, description)
416 , m_config (config)
417 {
418 }
419
iterate(void)420 TestCase::IterateResult FboRenderCase::iterate (void)
421 {
422 tcu::Vec4 clearColor = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f);
423 glu::RenderContext& renderCtx = m_context.getRenderContext();
424 const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
425 tcu::TestLog& log = m_testCtx.getLog();
426 const char* failReason = DE_NULL;
427
428 // Position & size for context
429 deRandom rnd;
430 deRandom_init(&rnd, deStringHash(getName()));
431
432 int width = deMin32(renderTarget.getWidth(), 128);
433 int height = deMin32(renderTarget.getHeight(), 128);
434 int xMax = renderTarget.getWidth()-width+1;
435 int yMax = renderTarget.getHeight()-height+1;
436 int x = deRandom_getUint32(&rnd) % xMax;
437 int y = deRandom_getUint32(&rnd) % yMax;
438
439 tcu::Surface gles3Frame (width, height);
440 tcu::Surface refFrame (width, height);
441 GLenum gles3Error;
442 GLenum refError;
443
444 // Render using GLES3
445 try
446 {
447 sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
448
449 context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
450 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
451
452 render(context, gles3Frame); // Call actual render func
453 gles3Error = context.getError();
454 }
455 catch (const FboIncompleteException& e)
456 {
457 if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED)
458 {
459 // Mark test case as unsupported
460 log << e;
461 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
462 return STOP;
463 }
464 else
465 throw; // Propagate error
466 }
467
468 // Render reference image
469 {
470 sglr::ReferenceContextBuffers buffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height);
471 sglr::ReferenceContext context (sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
472
473 context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
474 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
475
476 render(context, refFrame);
477 refError = context.getError();
478 }
479
480 // Compare error codes
481 bool errorCodesOk = (gles3Error == refError);
482
483 if (!errorCodesOk)
484 {
485 log << tcu::TestLog::Message << "Error code mismatch: got " << glu::getErrorStr(gles3Error) << ", expected " << glu::getErrorStr(refError) << tcu::TestLog::EndMessage;
486 failReason = "Got unexpected error";
487 }
488
489 // Compare images
490 bool imagesOk = compare(refFrame, gles3Frame);
491
492 if (!imagesOk && !failReason)
493 failReason = "Image comparison failed";
494
495 // Store test result
496 bool isOk = errorCodesOk && imagesOk;
497 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
498 isOk ? "Pass" : failReason);
499
500 return STOP;
501 }
502
compare(const tcu::Surface & reference,const tcu::Surface & result)503 bool FboRenderCase::compare (const tcu::Surface& reference, const tcu::Surface& result)
504 {
505 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_config.colorFormat), tcu::RGBA(12, 12, 12, 12)));
506
507 return tcu::bilinearCompare(m_testCtx.getLog(), "ComparisonResult", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
508 }
509
510 namespace FboCases
511 {
512
513 class StencilClearsTest : public FboRenderCase
514 {
515 public:
516 StencilClearsTest (Context& context, const FboConfig& config);
~StencilClearsTest(void)517 virtual ~StencilClearsTest (void) {};
518
519 void render (sglr::Context& context, Surface& dst);
520 };
521
StencilClearsTest(Context & context,const FboConfig & config)522 StencilClearsTest::StencilClearsTest (Context& context, const FboConfig& config)
523 : FboRenderCase (context, config.getName().c_str(), "Stencil clears", config)
524 {
525 }
526
render(sglr::Context & context,Surface & dst)527 void StencilClearsTest::render (sglr::Context& context, Surface& dst)
528 {
529 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat);
530 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat);
531 glu::DataType fboOutputType = getFragmentOutputType(colorFormat);
532 tcu::TextureFormatInfo fboRangeInfo = tcu::getTextureFormatInfo(colorFormat);
533 Vec4 fboOutScale = fboRangeInfo.valueMax - fboRangeInfo.valueMin;
534 Vec4 fboOutBias = fboRangeInfo.valueMin;
535
536 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, fboOutputType);
537 Texture2DShader texFromFboShader (DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4);
538
539 deUint32 texToFboShaderID = context.createProgram(&texToFboShader);
540 deUint32 texFromFboShaderID = context.createProgram(&texFromFboShader);
541
542 deUint32 metaballsTex = 1;
543 deUint32 quadsTex = 2;
544 int width = 128;
545 int height = 128;
546
547 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
548 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
549
550 createQuadsTex2D(context, quadsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height);
551 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height);
552
553 Framebuffer fbo(context, m_config, width, height);
554 fbo.checkCompleteness();
555
556 // Bind framebuffer and clear
557 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
558 context.viewport(0, 0, width, height);
559 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
560 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
561
562 // Do stencil clears
563 context.enable(GL_SCISSOR_TEST);
564 context.scissor(10, 16, 32, 120);
565 context.clearStencil(1);
566 context.clear(GL_STENCIL_BUFFER_BIT);
567 context.scissor(16, 32, 100, 64);
568 context.clearStencil(2);
569 context.clear(GL_STENCIL_BUFFER_BIT);
570 context.disable(GL_SCISSOR_TEST);
571
572 // Draw 2 textures with stecil tests
573 context.enable(GL_STENCIL_TEST);
574
575 context.bindTexture(GL_TEXTURE_2D, quadsTex);
576 context.stencilFunc(GL_EQUAL, 1, 0xffu);
577
578 texToFboShader.setUniforms(context, texToFboShaderID);
579 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
580
581 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
582 context.stencilFunc(GL_EQUAL, 2, 0xffu);
583
584 texToFboShader.setUniforms(context, texToFboShaderID);
585 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
586
587 context.disable(GL_STENCIL_TEST);
588
589 if (fbo.getConfig().colorType == GL_TEXTURE_2D)
590 {
591 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
592 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer());
593 context.viewport(0, 0, context.getWidth(), context.getHeight());
594
595 texFromFboShader.setUniforms(context, texFromFboShaderID);
596 sglr::drawQuad(context, texFromFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
597
598 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
599 }
600 else
601 readPixels(context, dst, 0, 0, width, height, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
602 }
603
604 class SharedColorbufferTest : public FboRenderCase
605 {
606 public:
607 SharedColorbufferTest (Context& context, const FboConfig& config);
~SharedColorbufferTest(void)608 virtual ~SharedColorbufferTest (void) {};
609
610 void render (sglr::Context& context, Surface& dst);
611 };
612
SharedColorbufferTest(Context & context,const FboConfig & config)613 SharedColorbufferTest::SharedColorbufferTest (Context& context, const FboConfig& config)
614 : FboRenderCase (context, config.getName().c_str(), "Shared colorbuffer", config)
615 {
616 }
617
render(sglr::Context & context,Surface & dst)618 void SharedColorbufferTest::render (sglr::Context& context, Surface& dst)
619 {
620 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
621 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4);
622 deUint32 texShaderID = context.createProgram(&texShader);
623 deUint32 flatShaderID = context.createProgram(&flatShader);
624
625 int width = 128;
626 int height = 128;
627 deUint32 quadsTex = 1;
628 deUint32 metaballsTex = 2;
629 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0;
630
631 context.disable(GL_DITHER);
632
633 // Textures
634 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
635 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, 64, 64);
636
637 context.viewport(0, 0, width, height);
638
639 // Fbo A
640 Framebuffer fboA(context, m_config, width, height);
641 fboA.checkCompleteness();
642
643 // Fbo B - don't create colorbuffer
644 FboConfig cfg = m_config;
645 cfg.buffers &= ~GL_COLOR_BUFFER_BIT;
646 cfg.colorType = GL_NONE;
647 cfg.colorFormat = GL_NONE;
648 Framebuffer fboB(context, cfg, width, height);
649
650 // Attach color buffer from fbo A
651 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
652 switch (m_config.colorType)
653 {
654 case GL_TEXTURE_2D:
655 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboA.getColorBuffer(), 0);
656 break;
657
658 case GL_RENDERBUFFER:
659 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fboA.getColorBuffer());
660 break;
661
662 default:
663 DE_ASSERT(DE_FALSE);
664 }
665
666 // Clear depth and stencil in fbo B
667 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
668
669 // Render quads to fbo 1, with depth 0.0
670 context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer());
671 context.bindTexture(GL_TEXTURE_2D, quadsTex);
672 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
673 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
674
675 if (stencil)
676 {
677 // Stencil to 1 in fbo A
678 context.clearStencil(1);
679 context.clear(GL_STENCIL_BUFFER_BIT);
680 }
681
682 texShader.setUniforms(context, texShaderID);
683
684 context.enable(GL_DEPTH_TEST);
685 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
686 context.disable(GL_DEPTH_TEST);
687
688 // Blend metaballs to fbo 2
689 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
690 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
691 context.enable(GL_BLEND);
692 context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
693 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
694
695 // Render small quad that is only visible if depth buffer is not shared with fbo A - or there is no depth bits
696 context.bindTexture(GL_TEXTURE_2D, quadsTex);
697 context.enable(GL_DEPTH_TEST);
698 sglr::drawQuad(context, texShaderID, Vec3(0.5f, 0.5f, 0.5f), Vec3(1.0f, 1.0f, 0.5f));
699 context.disable(GL_DEPTH_TEST);
700
701 if (stencil)
702 {
703 flatShader.setColor(context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
704
705 // Clear subset of stencil buffer to 1
706 context.enable(GL_SCISSOR_TEST);
707 context.scissor(10, 10, 12, 25);
708 context.clearStencil(1);
709 context.clear(GL_STENCIL_BUFFER_BIT);
710 context.disable(GL_SCISSOR_TEST);
711
712 // Render quad with stencil mask == 1
713 context.enable(GL_STENCIL_TEST);
714 context.stencilFunc(GL_EQUAL, 1, 0xffu);
715 sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
716 context.disable(GL_STENCIL_TEST);
717 }
718
719 // Get results
720 if (fboA.getConfig().colorType == GL_TEXTURE_2D)
721 {
722 texShader.setUniforms(context, texShaderID);
723
724 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
725 context.bindTexture(GL_TEXTURE_2D, fboA.getColorBuffer());
726 context.viewport(0, 0, context.getWidth(), context.getHeight());
727 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
728 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
729 }
730 else
731 readPixels(context, dst, 0, 0, width, height, glu::mapGLInternalFormat(fboA.getConfig().colorFormat), Vec4(1.0f), Vec4(0.0f));
732 }
733
734 class SharedColorbufferClearsTest : public FboRenderCase
735 {
736 public:
737 SharedColorbufferClearsTest (Context& context, const FboConfig& config);
~SharedColorbufferClearsTest(void)738 virtual ~SharedColorbufferClearsTest (void) {}
739
740 void render (sglr::Context& context, Surface& dst);
741 };
742
SharedColorbufferClearsTest(Context & context,const FboConfig & config)743 SharedColorbufferClearsTest::SharedColorbufferClearsTest (Context& context, const FboConfig& config)
744 : FboRenderCase (context, config.getName().c_str(), "Shared colorbuffer clears", config)
745 {
746 }
747
render(sglr::Context & context,Surface & dst)748 void SharedColorbufferClearsTest::render (sglr::Context& context, Surface& dst)
749 {
750 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat);
751 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat);
752 int width = 128;
753 int height = 128;
754 deUint32 colorbuffer = 1;
755
756 // Check for format support.
757 checkColorFormatSupport(context, m_config.colorFormat);
758
759 // Single colorbuffer
760 if (m_config.colorType == GL_TEXTURE_2D)
761 {
762 context.bindTexture(GL_TEXTURE_2D, colorbuffer);
763 context.texImage2D(GL_TEXTURE_2D, 0, m_config.colorFormat, width, height);
764 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
765 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
766 }
767 else
768 {
769 DE_ASSERT(m_config.colorType == GL_RENDERBUFFER);
770 context.bindRenderbuffer(GL_RENDERBUFFER, colorbuffer);
771 context.renderbufferStorage(GL_RENDERBUFFER, m_config.colorFormat, width, height);
772 }
773
774 // Multiple framebuffers sharing the colorbuffer
775 for (int fbo = 1; fbo <= 3; fbo++)
776 {
777 context.bindFramebuffer(GL_FRAMEBUFFER, fbo);
778
779 if (m_config.colorType == GL_TEXTURE_2D)
780 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
781 else
782 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer);
783 }
784
785 context.bindFramebuffer(GL_FRAMEBUFFER, 1);
786
787 // Check completeness
788 {
789 GLenum status = context.checkFramebufferStatus(GL_FRAMEBUFFER);
790 if (status != GL_FRAMEBUFFER_COMPLETE)
791 throw FboIncompleteException(status, __FILE__, __LINE__);
792 }
793
794 // Render to them
795 context.viewport(0, 0, width, height);
796 context.clearColor(0.0f, 0.0f, 1.0f, 1.0f);
797 context.clear(GL_COLOR_BUFFER_BIT);
798
799 context.enable(GL_SCISSOR_TEST);
800
801 context.bindFramebuffer(GL_FRAMEBUFFER, 2);
802 context.clearColor(0.6f, 0.0f, 0.0f, 1.0f);
803 context.scissor(10, 10, 64, 64);
804 context.clear(GL_COLOR_BUFFER_BIT);
805 context.clearColor(0.0f, 0.6f, 0.0f, 1.0f);
806 context.scissor(60, 60, 40, 20);
807 context.clear(GL_COLOR_BUFFER_BIT);
808
809 context.bindFramebuffer(GL_FRAMEBUFFER, 3);
810 context.clearColor(0.0f, 0.0f, 0.6f, 1.0f);
811 context.scissor(20, 20, 100, 10);
812 context.clear(GL_COLOR_BUFFER_BIT);
813
814 context.bindFramebuffer(GL_FRAMEBUFFER, 1);
815 context.clearColor(0.6f, 0.0f, 0.6f, 1.0f);
816 context.scissor(20, 20, 5, 100);
817 context.clear(GL_COLOR_BUFFER_BIT);
818
819 context.disable(GL_SCISSOR_TEST);
820
821 if (m_config.colorType == GL_TEXTURE_2D)
822 {
823 Texture2DShader shader(DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4);
824 deUint32 shaderID = context.createProgram(&shader);
825
826 shader.setUniforms(context, shaderID);
827
828 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
829 context.viewport(0, 0, context.getWidth(), context.getHeight());
830 sglr::drawQuad(context, shaderID, Vec3(-0.9f, -0.9f, 0.0f), Vec3(0.9f, 0.9f, 0.0f));
831 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
832 }
833 else
834 readPixels(context, dst, 0, 0, width, height, colorFormat, Vec4(1.0f), Vec4(0.0f));
835 }
836
837 class SharedDepthStencilTest : public FboRenderCase
838 {
839 public:
840 SharedDepthStencilTest (Context& context, const FboConfig& config);
~SharedDepthStencilTest(void)841 virtual ~SharedDepthStencilTest (void) {};
842
843 static bool isConfigSupported (const FboConfig& config);
844 void render (sglr::Context& context, Surface& dst);
845 };
846
SharedDepthStencilTest(Context & context,const FboConfig & config)847 SharedDepthStencilTest::SharedDepthStencilTest (Context& context, const FboConfig& config)
848 : FboRenderCase (context, config.getName().c_str(), "Shared depth/stencilbuffer", config)
849 {
850 }
851
isConfigSupported(const FboConfig & config)852 bool SharedDepthStencilTest::isConfigSupported (const FboConfig& config)
853 {
854 return (config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0;
855 }
856
render(sglr::Context & context,Surface & dst)857 void SharedDepthStencilTest::render (sglr::Context& context, Surface& dst)
858 {
859 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
860 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4);
861 deUint32 texShaderID = context.createProgram(&texShader);
862 deUint32 flatShaderID = context.createProgram(&flatShader);
863 int width = 128;
864 int height = 128;
865 // bool depth = (m_config.buffers & GL_DEPTH_BUFFER_BIT) != 0;
866 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0;
867
868 // Textures
869 deUint32 metaballsTex = 5;
870 deUint32 quadsTex = 6;
871 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
872 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
873
874 context.viewport(0, 0, width, height);
875
876 // Fbo A
877 Framebuffer fboA(context, m_config, width, height);
878 fboA.checkCompleteness();
879
880 // Fbo B
881 FboConfig cfg = m_config;
882 cfg.buffers &= ~(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
883 cfg.depthStencilType = GL_NONE;
884 cfg.depthStencilFormat = GL_NONE;
885 Framebuffer fboB(context, cfg, width, height);
886
887 // Bind depth/stencil buffers from fbo A to fbo B
888 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
889 for (int ndx = 0; ndx < 2; ndx++)
890 {
891 deUint32 bit = ndx ? GL_STENCIL_BUFFER_BIT : GL_DEPTH_BUFFER_BIT;
892 deUint32 point = ndx ? GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
893
894 if ((m_config.buffers & bit) == 0)
895 continue;
896
897 switch (m_config.depthStencilType)
898 {
899 case GL_TEXTURE_2D: context.framebufferTexture2D(GL_FRAMEBUFFER, point, GL_TEXTURE_2D, fboA.getDepthStencilBuffer(), 0); break;
900 case GL_RENDERBUFFER: context.framebufferRenderbuffer(GL_FRAMEBUFFER, point, GL_RENDERBUFFER, fboA.getDepthStencilBuffer()); break;
901 default:
902 TCU_FAIL("Not implemented");
903 }
904 }
905
906 // Setup uniforms
907 texShader.setUniforms(context, texShaderID);
908
909 // Clear color to red and stencil to 1 in fbo B.
910 context.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
911 context.clearStencil(1);
912 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
913
914 context.enable(GL_DEPTH_TEST);
915
916 // Render quad to fbo A
917 context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer());
918 context.bindTexture(GL_TEXTURE_2D, quadsTex);
919 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
920
921 if (stencil)
922 {
923 // Clear subset of stencil buffer to 0 in fbo A
924 context.enable(GL_SCISSOR_TEST);
925 context.scissor(10, 10, 12, 25);
926 context.clearStencil(0);
927 context.clear(GL_STENCIL_BUFFER_BIT);
928 context.disable(GL_SCISSOR_TEST);
929 }
930
931 // Render metaballs to fbo B
932 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
933 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
934 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
935
936 context.disable(GL_DEPTH_TEST);
937
938 if (stencil)
939 {
940 // Render quad with stencil mask == 0
941 context.enable(GL_STENCIL_TEST);
942 context.stencilFunc(GL_EQUAL, 0, 0xffu);
943 context.useProgram(flatShaderID);
944 flatShader.setColor(context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
945 sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
946 context.disable(GL_STENCIL_TEST);
947 }
948
949 if (m_config.colorType == GL_TEXTURE_2D)
950 {
951 // Render both to screen
952 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
953 context.viewport(0, 0, context.getWidth(), context.getHeight());
954 context.bindTexture(GL_TEXTURE_2D, fboA.getColorBuffer());
955 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f));
956 context.bindTexture(GL_TEXTURE_2D, fboB.getColorBuffer());
957 sglr::drawQuad(context, texShaderID, Vec3(0.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
958
959 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
960 }
961 else
962 {
963 // Read results from fbo B
964 readPixels(context, dst, 0, 0, width, height, glu::mapGLInternalFormat(m_config.colorFormat), Vec4(1.0f), Vec4(0.0f));
965 }
966 }
967
968 #if 0
969 class TexSubImageAfterRenderTest : public FboRenderCase
970 {
971 public:
972 TexSubImageAfterRenderTest (Context& context, const FboConfig& config);
973 virtual ~TexSubImageAfterRenderTest (void) {}
974
975 void render (sglr::Context& context, Surface& dst);
976 };
977
978 TexSubImageAfterRenderTest::TexSubImageAfterRenderTest (Context& context, const FboConfig& config)
979 : FboRenderCase(context, (string("after_render_") + config.getName()).c_str(), "TexSubImage after rendering to texture", config)
980 {
981 }
982
983 void TexSubImageAfterRenderTest::render (sglr::Context& context, Surface& dst)
984 {
985 using sglr::TexturedQuadOp;
986
987 bool isRGBA = true;
988
989 Surface fourQuads(Surface::PIXELFORMAT_RGB, 64, 64);
990 tcu::SurfaceUtil::fillWithFourQuads(fourQuads);
991
992 Surface metaballs(isRGBA ? Surface::PIXELFORMAT_RGBA : Surface::PIXELFORMAT_RGB, 64, 64);
993 tcu::SurfaceUtil::fillWithMetaballs(metaballs, 5, 3);
994
995 deUint32 fourQuadsTex = 1;
996 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
997 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
998 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, fourQuads);
999
1000 context.bindFramebuffer(GL_FRAMEBUFFER, 1);
1001
1002 deUint32 fboTex = 2;
1003 context.bindTexture(GL_TEXTURE_2D, fboTex);
1004 context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128);
1005 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1006 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
1007
1008 // Render to fbo
1009 context.viewport(0, 0, 128, 128);
1010 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
1011 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0));
1012
1013 // Update texture using TexSubImage2D
1014 context.bindTexture(GL_TEXTURE_2D, fboTex);
1015 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, metaballs);
1016
1017 // Draw to screen
1018 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
1019 context.viewport(0, 0, context.getWidth(), context.getHeight());
1020 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0));
1021 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
1022 }
1023
1024 class TexSubImageBetweenRenderTest : public FboRenderCase
1025 {
1026 public:
1027 TexSubImageBetweenRenderTest (Context& context, const FboConfig& config);
1028 virtual ~TexSubImageBetweenRenderTest (void) {}
1029
1030 void render (sglr::Context& context, Surface& dst);
1031 };
1032
1033 TexSubImageBetweenRenderTest::TexSubImageBetweenRenderTest (Context& context, const FboConfig& config)
1034 : FboRenderCase(context, (string("between_render_") + config.getName()).c_str(), "TexSubImage between rendering calls", config)
1035 {
1036 }
1037
1038 void TexSubImageBetweenRenderTest::render (sglr::Context& context, Surface& dst)
1039 {
1040 using sglr::TexturedQuadOp;
1041 using sglr::BlendTextureOp;
1042
1043 bool isRGBA = true;
1044
1045 Surface fourQuads(Surface::PIXELFORMAT_RGB, 64, 64);
1046 tcu::SurfaceUtil::fillWithFourQuads(fourQuads);
1047
1048 Surface metaballs(isRGBA ? Surface::PIXELFORMAT_RGBA : Surface::PIXELFORMAT_RGB, 64, 64);
1049 tcu::SurfaceUtil::fillWithMetaballs(metaballs, 5, 3);
1050
1051 Surface metaballs2(Surface::PIXELFORMAT_RGBA, 64, 64);
1052 tcu::SurfaceUtil::fillWithMetaballs(metaballs2, 5, 4);
1053
1054 deUint32 metaballsTex = 3;
1055 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
1056 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1057 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, metaballs2);
1058
1059 deUint32 fourQuadsTex = 1;
1060 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
1061 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1062 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, fourQuads);
1063
1064 context.bindFramebuffer(GL_FRAMEBUFFER, 1);
1065
1066 deUint32 fboTex = 2;
1067 context.bindTexture(GL_TEXTURE_2D, fboTex);
1068 context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128);
1069 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1070 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
1071
1072 // Render to fbo
1073 context.viewport(0, 0, 128, 128);
1074 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex);
1075 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0));
1076
1077 // Update texture using TexSubImage2D
1078 context.bindTexture(GL_TEXTURE_2D, fboTex);
1079 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, metaballs);
1080
1081 // Render again to fbo
1082 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
1083 context.draw(BlendTextureOp(0));
1084
1085 // Draw to screen
1086 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
1087 context.viewport(0, 0, context.getWidth(), context.getHeight());
1088 context.bindTexture(GL_TEXTURE_2D, fboTex);
1089 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0));
1090
1091 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
1092 }
1093 #endif
1094
1095 class ResizeTest : public FboRenderCase
1096 {
1097 public:
1098 ResizeTest (Context& context, const FboConfig& config);
~ResizeTest(void)1099 virtual ~ResizeTest (void) {}
1100
1101 void render (sglr::Context& context, Surface& dst);
1102 };
1103
ResizeTest(Context & context,const FboConfig & config)1104 ResizeTest::ResizeTest (Context& context, const FboConfig& config)
1105 : FboRenderCase (context, config.getName().c_str(), "Resize framebuffer", config)
1106 {
1107 }
1108
render(sglr::Context & context,Surface & dst)1109 void ResizeTest::render (sglr::Context& context, Surface& dst)
1110 {
1111 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat);
1112 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat);
1113 glu::DataType fboOutputType = getFragmentOutputType(colorFormat);
1114 tcu::TextureFormatInfo fboRangeInfo = tcu::getTextureFormatInfo(colorFormat);
1115 Vec4 fboOutScale = fboRangeInfo.valueMax - fboRangeInfo.valueMin;
1116 Vec4 fboOutBias = fboRangeInfo.valueMin;
1117
1118 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, fboOutputType);
1119 Texture2DShader texFromFboShader (DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4);
1120 FlatColorShader flatShader (fboOutputType);
1121 deUint32 texToFboShaderID = context.createProgram(&texToFboShader);
1122 deUint32 texFromFboShaderID = context.createProgram(&texFromFboShader);
1123 deUint32 flatShaderID = context.createProgram(&flatShader);
1124
1125 deUint32 quadsTex = 1;
1126 deUint32 metaballsTex = 2;
1127 bool depth = (m_config.buffers & GL_DEPTH_BUFFER_BIT) != 0;
1128 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0;
1129 int initialWidth = 128;
1130 int initialHeight = 128;
1131 int newWidth = 64;
1132 int newHeight = 32;
1133
1134 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
1135 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
1136
1137 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
1138 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 32, 32);
1139
1140 Framebuffer fbo(context, m_config, initialWidth, initialHeight);
1141 fbo.checkCompleteness();
1142
1143 // Setup shaders
1144 texToFboShader.setUniforms (context, texToFboShaderID);
1145 texFromFboShader.setUniforms(context, texFromFboShaderID);
1146 flatShader.setColor (context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f) * fboOutScale + fboOutBias);
1147
1148 // Render quads
1149 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
1150 context.viewport(0, 0, initialWidth, initialHeight);
1151 clearColorBuffer(context, colorFormat, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
1152 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1153 context.bindTexture(GL_TEXTURE_2D, quadsTex);
1154 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1155
1156 if (fbo.getConfig().colorType == GL_TEXTURE_2D)
1157 {
1158 // Render fbo to screen
1159 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
1160 context.viewport(0, 0, context.getWidth(), context.getHeight());
1161 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer());
1162 sglr::drawQuad(context, texFromFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1163
1164 // Restore binding
1165 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
1166 }
1167
1168 // Resize buffers
1169 switch (fbo.getConfig().colorType)
1170 {
1171 case GL_TEXTURE_2D:
1172 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer());
1173 context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().colorFormat, newWidth, newHeight);
1174 break;
1175
1176 case GL_RENDERBUFFER:
1177 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getColorBuffer());
1178 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().colorFormat, newWidth, newHeight);
1179 break;
1180
1181 default:
1182 DE_ASSERT(DE_FALSE);
1183 }
1184
1185 if (depth || stencil)
1186 {
1187 switch (fbo.getConfig().depthStencilType)
1188 {
1189 case GL_TEXTURE_2D:
1190 context.bindTexture(GL_TEXTURE_2D, fbo.getDepthStencilBuffer());
1191 context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().depthStencilFormat, newWidth, newHeight);
1192 break;
1193
1194 case GL_RENDERBUFFER:
1195 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getDepthStencilBuffer());
1196 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().depthStencilFormat, newWidth, newHeight);
1197 break;
1198
1199 default:
1200 DE_ASSERT(false);
1201 }
1202 }
1203
1204 // Render to resized fbo
1205 context.viewport(0, 0, newWidth, newHeight);
1206 clearColorBuffer(context, colorFormat, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1207 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1208
1209 context.enable(GL_DEPTH_TEST);
1210
1211 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
1212 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
1213
1214 context.bindTexture(GL_TEXTURE_2D, quadsTex);
1215 sglr::drawQuad(context, texToFboShaderID, Vec3(0.0f, 0.0f, -1.0f), Vec3(+1.0f, +1.0f, 1.0f));
1216
1217 context.disable(GL_DEPTH_TEST);
1218
1219 if (stencil)
1220 {
1221 context.enable(GL_SCISSOR_TEST);
1222 context.clearStencil(1);
1223 context.scissor(10, 10, 5, 15);
1224 context.clear(GL_STENCIL_BUFFER_BIT);
1225 context.disable(GL_SCISSOR_TEST);
1226
1227 context.enable(GL_STENCIL_TEST);
1228 context.stencilFunc(GL_EQUAL, 1, 0xffu);
1229 sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
1230 context.disable(GL_STENCIL_TEST);
1231 }
1232
1233 if (m_config.colorType == GL_TEXTURE_2D)
1234 {
1235 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
1236 context.viewport(0, 0, context.getWidth(), context.getHeight());
1237 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer());
1238 sglr::drawQuad(context, texFromFboShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(0.5f, 0.5f, 0.0f));
1239 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
1240 }
1241 else
1242 readPixels(context, dst, 0, 0, newWidth, newHeight, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
1243 }
1244
1245 class RecreateBuffersTest : public FboRenderCase
1246 {
1247 public:
1248 RecreateBuffersTest (Context& context, const FboConfig& config, deUint32 buffers, bool rebind);
~RecreateBuffersTest(void)1249 virtual ~RecreateBuffersTest (void) {}
1250
1251 void render (sglr::Context& context, Surface& dst);
1252
1253 private:
1254 deUint32 m_buffers;
1255 bool m_rebind;
1256 };
1257
RecreateBuffersTest(Context & context,const FboConfig & config,deUint32 buffers,bool rebind)1258 RecreateBuffersTest::RecreateBuffersTest (Context& context, const FboConfig& config, deUint32 buffers, bool rebind)
1259 : FboRenderCase (context, (string(config.getName()) + (rebind ? "" : "_no_rebind")).c_str(), "Recreate buffers", config)
1260 , m_buffers (buffers)
1261 , m_rebind (rebind)
1262 {
1263 }
1264
render(sglr::Context & ctx,Surface & dst)1265 void RecreateBuffersTest::render (sglr::Context& ctx, Surface& dst)
1266 {
1267 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat);
1268 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat);
1269 glu::DataType fboOutputType = getFragmentOutputType(colorFormat);
1270 tcu::TextureFormatInfo fboRangeInfo = tcu::getTextureFormatInfo(colorFormat);
1271 Vec4 fboOutScale = fboRangeInfo.valueMax - fboRangeInfo.valueMin;
1272 Vec4 fboOutBias = fboRangeInfo.valueMin;
1273
1274 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, fboOutputType);
1275 Texture2DShader texFromFboShader (DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4);
1276 FlatColorShader flatShader (fboOutputType);
1277 deUint32 texToFboShaderID = ctx.createProgram(&texToFboShader);
1278 deUint32 texFromFboShaderID = ctx.createProgram(&texFromFboShader);
1279 deUint32 flatShaderID = ctx.createProgram(&flatShader);
1280
1281 int width = 128;
1282 int height = 128;
1283 deUint32 metaballsTex = 1;
1284 deUint32 quadsTex = 2;
1285 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0;
1286
1287 createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
1288 createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
1289
1290 Framebuffer fbo(ctx, m_config, width, height);
1291 fbo.checkCompleteness();
1292
1293 // Setup shaders
1294 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
1295 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
1296 texToFboShader.setUniforms (ctx, texToFboShaderID);
1297 texFromFboShader.setUniforms(ctx, texFromFboShaderID);
1298 flatShader.setColor (ctx, flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f) * fboOutScale + fboOutBias);
1299
1300 // Draw scene
1301 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
1302 ctx.viewport(0, 0, width, height);
1303 clearColorBuffer(ctx, colorFormat, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1304 ctx.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1305
1306 ctx.enable(GL_DEPTH_TEST);
1307
1308 ctx.bindTexture(GL_TEXTURE_2D, quadsTex);
1309 sglr::drawQuad(ctx, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1310
1311 ctx.disable(GL_DEPTH_TEST);
1312
1313 if (stencil)
1314 {
1315 ctx.enable(GL_SCISSOR_TEST);
1316 ctx.scissor(width/4, height/4, width/2, height/2);
1317 ctx.clearStencil(1);
1318 ctx.clear(GL_STENCIL_BUFFER_BIT);
1319 ctx.disable(GL_SCISSOR_TEST);
1320 }
1321
1322 // Recreate buffers
1323 if (!m_rebind)
1324 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
1325
1326 DE_ASSERT((m_buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == 0 ||
1327 (m_buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == (m_config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)));
1328
1329 // Recreate.
1330 for (int ndx = 0; ndx < 2; ndx++)
1331 {
1332 deUint32 bit = ndx == 0 ? GL_COLOR_BUFFER_BIT
1333 : (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
1334 deUint32 type = ndx == 0 ? fbo.getConfig().colorType
1335 : fbo.getConfig().depthStencilType;
1336 deUint32 format = ndx == 0 ? fbo.getConfig().colorFormat
1337 : fbo.getConfig().depthStencilFormat;
1338 deUint32 buf = ndx == 0 ? fbo.getColorBuffer()
1339 : fbo.getDepthStencilBuffer();
1340
1341 if ((m_buffers & bit) == 0)
1342 continue;
1343
1344 switch (type)
1345 {
1346 case GL_TEXTURE_2D:
1347 ctx.deleteTextures(1, &buf);
1348 ctx.bindTexture(GL_TEXTURE_2D, buf);
1349 ctx.texImage2D(GL_TEXTURE_2D, 0, format, width, height);
1350 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1351 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1352 break;
1353
1354 case GL_RENDERBUFFER:
1355 ctx.deleteRenderbuffers(1, &buf);
1356 ctx.bindRenderbuffer(GL_RENDERBUFFER, buf);
1357 ctx.renderbufferStorage(GL_RENDERBUFFER, format, width, height);
1358 break;
1359
1360 default:
1361 DE_ASSERT(false);
1362 }
1363 }
1364
1365 // Rebind.
1366 if (m_rebind)
1367 {
1368 for (int ndx = 0; ndx < 3; ndx++)
1369 {
1370 deUint32 bit = ndx == 0 ? GL_COLOR_BUFFER_BIT :
1371 ndx == 1 ? GL_DEPTH_BUFFER_BIT :
1372 ndx == 2 ? GL_STENCIL_BUFFER_BIT : 0;
1373 deUint32 point = ndx == 0 ? GL_COLOR_ATTACHMENT0 :
1374 ndx == 1 ? GL_DEPTH_ATTACHMENT :
1375 ndx == 2 ? GL_STENCIL_ATTACHMENT : 0;
1376 deUint32 type = ndx == 0 ? fbo.getConfig().colorType
1377 : fbo.getConfig().depthStencilType;
1378 deUint32 buf = ndx == 0 ? fbo.getColorBuffer()
1379 : fbo.getDepthStencilBuffer();
1380
1381 if ((m_buffers & bit) == 0)
1382 continue;
1383
1384 switch (type)
1385 {
1386 case GL_TEXTURE_2D:
1387 ctx.framebufferTexture2D(GL_FRAMEBUFFER, point, GL_TEXTURE_2D, buf, 0);
1388 break;
1389
1390 case GL_RENDERBUFFER:
1391 ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, point, GL_RENDERBUFFER, buf);
1392 break;
1393
1394 default:
1395 DE_ASSERT(false);
1396 }
1397 }
1398 }
1399
1400 if (!m_rebind)
1401 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
1402
1403 ctx.clearStencil(0);
1404 ctx.clear(m_buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); // \note Clear only buffers that were re-created
1405 if (m_buffers & GL_COLOR_BUFFER_BIT)
1406 {
1407 // Clearing of integer buffers is undefined so do clearing by rendering flat color.
1408 sglr::drawQuad(ctx, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1409 }
1410
1411 ctx.enable(GL_DEPTH_TEST);
1412
1413 if (stencil)
1414 {
1415 // \note Stencil test enabled only if we have stencil buffer
1416 ctx.enable(GL_STENCIL_TEST);
1417 ctx.stencilFunc(GL_EQUAL, 0, 0xffu);
1418 }
1419 ctx.bindTexture(GL_TEXTURE_2D, metaballsTex);
1420 sglr::drawQuad(ctx, texToFboShaderID, Vec3(-1.0f, -1.0f, 1.0f), Vec3(1.0f, 1.0f, -1.0f));
1421 if (stencil)
1422 ctx.disable(GL_STENCIL_TEST);
1423
1424 ctx.disable(GL_DEPTH_TEST);
1425
1426 if (fbo.getConfig().colorType == GL_TEXTURE_2D)
1427 {
1428 // Unbind fbo
1429 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
1430
1431 // Draw to screen
1432 ctx.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer());
1433 ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
1434 sglr::drawQuad(ctx, texFromFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
1435
1436 // Read from screen
1437 ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
1438 }
1439 else
1440 {
1441 // Read from fbo
1442 readPixels(ctx, dst, 0, 0, width, height, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
1443 }
1444 }
1445
1446 } // FboCases
1447
FboRenderTestGroup(Context & context)1448 FboRenderTestGroup::FboRenderTestGroup (Context& context)
1449 : TestCaseGroup(context, "render", "Rendering Tests")
1450 {
1451 }
1452
~FboRenderTestGroup(void)1453 FboRenderTestGroup::~FboRenderTestGroup (void)
1454 {
1455 }
1456
init(void)1457 void FboRenderTestGroup::init (void)
1458 {
1459 static const deUint32 objectTypes[] =
1460 {
1461 GL_TEXTURE_2D,
1462 GL_RENDERBUFFER
1463 };
1464
1465 enum FormatType
1466 {
1467 FORMATTYPE_FLOAT = 0,
1468 FORMATTYPE_FIXED,
1469 FORMATTYPE_INT,
1470 FORMATTYPE_UINT,
1471
1472 FORMATTYPE_LAST
1473 };
1474
1475 // Required by specification.
1476 static const struct
1477 {
1478 deUint32 format;
1479 FormatType type;
1480 } colorFormats[] =
1481 {
1482 { GL_RGBA32F, FORMATTYPE_FLOAT },
1483 { GL_RGBA32I, FORMATTYPE_INT },
1484 { GL_RGBA32UI, FORMATTYPE_UINT },
1485 { GL_RGBA16F, FORMATTYPE_FLOAT },
1486 { GL_RGBA16I, FORMATTYPE_INT },
1487 { GL_RGBA16UI, FORMATTYPE_UINT },
1488 { GL_RGB16F, FORMATTYPE_FLOAT },
1489 { GL_RGBA8, FORMATTYPE_FIXED },
1490 { GL_RGBA8I, FORMATTYPE_INT },
1491 { GL_RGBA8UI, FORMATTYPE_UINT },
1492 { GL_SRGB8_ALPHA8, FORMATTYPE_FIXED },
1493 { GL_RGB10_A2, FORMATTYPE_FIXED },
1494 { GL_RGB10_A2UI, FORMATTYPE_UINT },
1495 { GL_RGBA4, FORMATTYPE_FIXED },
1496 { GL_RGB5_A1, FORMATTYPE_FIXED },
1497 { GL_RGB8, FORMATTYPE_FIXED },
1498 { GL_RGB565, FORMATTYPE_FIXED },
1499 { GL_R11F_G11F_B10F, FORMATTYPE_FLOAT },
1500 { GL_RG32F, FORMATTYPE_FLOAT },
1501 { GL_RG32I, FORMATTYPE_INT },
1502 { GL_RG32UI, FORMATTYPE_UINT },
1503 { GL_RG16F, FORMATTYPE_FLOAT },
1504 { GL_RG16I, FORMATTYPE_INT },
1505 { GL_RG16UI, FORMATTYPE_UINT },
1506 { GL_RG8, FORMATTYPE_FLOAT },
1507 { GL_RG8I, FORMATTYPE_INT },
1508 { GL_RG8UI, FORMATTYPE_UINT },
1509 { GL_R32F, FORMATTYPE_FLOAT },
1510 { GL_R32I, FORMATTYPE_INT },
1511 { GL_R32UI, FORMATTYPE_UINT },
1512 { GL_R16F, FORMATTYPE_FLOAT },
1513 { GL_R16I, FORMATTYPE_INT },
1514 { GL_R16UI, FORMATTYPE_UINT },
1515 { GL_R8, FORMATTYPE_FLOAT },
1516 { GL_R8I, FORMATTYPE_INT },
1517 { GL_R8UI, FORMATTYPE_UINT }
1518 };
1519
1520 static const struct
1521 {
1522 deUint32 format;
1523 bool depth;
1524 bool stencil;
1525 } depthStencilFormats[] =
1526 {
1527 { GL_DEPTH_COMPONENT32F, true, false },
1528 { GL_DEPTH_COMPONENT24, true, false },
1529 { GL_DEPTH_COMPONENT16, true, false },
1530 { GL_DEPTH32F_STENCIL8, true, true },
1531 { GL_DEPTH24_STENCIL8, true, true },
1532 { GL_STENCIL_INDEX8, false, true }
1533 };
1534
1535 using namespace FboCases;
1536
1537 // .stencil_clear
1538 tcu::TestCaseGroup* stencilClearGroup = new tcu::TestCaseGroup(m_testCtx, "stencil_clear", "Stencil buffer clears");
1539 addChild(stencilClearGroup);
1540 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++)
1541 {
1542 deUint32 colorType = GL_TEXTURE_2D;
1543 deUint32 stencilType = GL_RENDERBUFFER;
1544 deUint32 colorFmt = GL_RGBA8;
1545
1546 if (!depthStencilFormats[fmtNdx].stencil)
1547 continue;
1548
1549 FboConfig config(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, colorType, colorFmt, stencilType, depthStencilFormats[fmtNdx].format);
1550 stencilClearGroup->addChild(new StencilClearsTest(m_context, config));
1551 }
1552
1553 // .shared_colorbuffer_clear
1554 tcu::TestCaseGroup* sharedColorbufferClearGroup = new tcu::TestCaseGroup(m_testCtx, "shared_colorbuffer_clear", "Shader colorbuffer clears");
1555 addChild(sharedColorbufferClearGroup);
1556 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++)
1557 {
1558 // Clearing of integer buffers is undefined.
1559 if (colorFormats[colorFmtNdx].type == FORMATTYPE_INT || colorFormats[colorFmtNdx].type == FORMATTYPE_UINT)
1560 continue;
1561
1562 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1563 {
1564 FboConfig config(GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, GL_NONE, GL_NONE);
1565 sharedColorbufferClearGroup->addChild(new SharedColorbufferClearsTest(m_context, config));
1566 }
1567 }
1568
1569 // .shared_colorbuffer
1570 tcu::TestCaseGroup* sharedColorbufferGroup = new tcu::TestCaseGroup(m_testCtx, "shared_colorbuffer", "Shared colorbuffer tests");
1571 addChild(sharedColorbufferGroup);
1572 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++)
1573 {
1574 deUint32 depthStencilType = GL_RENDERBUFFER;
1575 deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8;
1576
1577 // Blending with integer buffers and fp32 targets is not supported.
1578 if (colorFormats[colorFmtNdx].type == FORMATTYPE_INT ||
1579 colorFormats[colorFmtNdx].type == FORMATTYPE_UINT ||
1580 colorFormats[colorFmtNdx].format == GL_RGBA32F ||
1581 colorFormats[colorFmtNdx].format == GL_RGB32F ||
1582 colorFormats[colorFmtNdx].format == GL_RG32F ||
1583 colorFormats[colorFmtNdx].format == GL_R32F)
1584 continue;
1585
1586 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1587 {
1588 FboConfig colorOnlyConfig (GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, GL_NONE, GL_NONE);
1589 FboConfig colorDepthConfig (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, depthStencilType, depthStencilFormat);
1590 FboConfig colorDepthStencilConfig (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, depthStencilType, depthStencilFormat);
1591
1592 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorOnlyConfig));
1593 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorDepthConfig));
1594 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorDepthStencilConfig));
1595 }
1596 }
1597
1598 // .shared_depth_stencil
1599 tcu::TestCaseGroup* sharedDepthStencilGroup = new tcu::TestCaseGroup(m_testCtx, "shared_depth_stencil", "Shared depth and stencil buffers");
1600 addChild(sharedDepthStencilGroup);
1601 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++)
1602 {
1603 deUint32 colorType = GL_TEXTURE_2D;
1604 deUint32 colorFmt = GL_RGBA8;
1605 bool depth = depthStencilFormats[fmtNdx].depth;
1606 bool stencil = depthStencilFormats[fmtNdx].stencil;
1607
1608 if (!depth)
1609 continue; // Not verified.
1610
1611 // Depth and stencil: both rbo and textures
1612 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1613 {
1614 FboConfig config(GL_COLOR_BUFFER_BIT|(depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0), colorType, colorFmt, objectTypes[typeNdx], depthStencilFormats[fmtNdx].format);
1615 sharedDepthStencilGroup->addChild(new SharedDepthStencilTest(m_context, config));
1616 }
1617 }
1618
1619 // .resize
1620 tcu::TestCaseGroup* resizeGroup = new tcu::TestCaseGroup(m_testCtx, "resize", "FBO resize tests");
1621 addChild(resizeGroup);
1622 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++)
1623 {
1624 deUint32 colorFormat = colorFormats[colorFmtNdx].format;
1625
1626 // Color-only.
1627 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1628 {
1629 FboConfig config(GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormat, GL_NONE, GL_NONE);
1630 resizeGroup->addChild(new ResizeTest(m_context, config));
1631 }
1632
1633 // For selected color formats tests depth & stencil variants.
1634 if (colorFormat == GL_RGBA8 || colorFormat == GL_RGBA16F)
1635 {
1636 for (int depthStencilFmtNdx = 0; depthStencilFmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); depthStencilFmtNdx++)
1637 {
1638 deUint32 colorType = GL_TEXTURE_2D;
1639 bool depth = depthStencilFormats[depthStencilFmtNdx].depth;
1640 bool stencil = depthStencilFormats[depthStencilFmtNdx].stencil;
1641
1642 // Depth and stencil: both rbo and textures
1643 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1644 {
1645 if (!depth && objectTypes[typeNdx] != GL_RENDERBUFFER)
1646 continue; // Not supported.
1647
1648 FboConfig config(GL_COLOR_BUFFER_BIT|(depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0),
1649 colorType, colorFormat,
1650 objectTypes[typeNdx], depthStencilFormats[depthStencilFmtNdx].format);
1651 resizeGroup->addChild(new ResizeTest(m_context, config));
1652 }
1653 }
1654 }
1655 }
1656
1657 // .recreate_color
1658 tcu::TestCaseGroup* recreateColorGroup = new tcu::TestCaseGroup(m_testCtx, "recreate_color", "Recreate colorbuffer tests");
1659 addChild(recreateColorGroup);
1660 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++)
1661 {
1662 deUint32 colorFormat = colorFormats[colorFmtNdx].format;
1663 deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8;
1664 deUint32 depthStencilType = GL_RENDERBUFFER;
1665
1666 // Color-only.
1667 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1668 {
1669 FboConfig config(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, objectTypes[typeNdx], colorFormat, depthStencilType, depthStencilFormat);
1670 recreateColorGroup->addChild(new RecreateBuffersTest(m_context, config, GL_COLOR_BUFFER_BIT, true /* rebind */));
1671 }
1672 }
1673
1674 // .recreate_depth_stencil
1675 tcu::TestCaseGroup* recreateDepthStencilGroup = new tcu::TestCaseGroup(m_testCtx, "recreate_depth_stencil", "Recreate depth and stencil buffers");
1676 addChild(recreateDepthStencilGroup);
1677 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++)
1678 {
1679 deUint32 colorType = GL_TEXTURE_2D;
1680 deUint32 colorFmt = GL_RGBA8;
1681 bool depth = depthStencilFormats[fmtNdx].depth;
1682 bool stencil = depthStencilFormats[fmtNdx].stencil;
1683
1684 // Depth and stencil: both rbo and textures
1685 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1686 {
1687 if (!depth && objectTypes[typeNdx] != GL_RENDERBUFFER)
1688 continue;
1689
1690 FboConfig config(GL_COLOR_BUFFER_BIT|(depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0), colorType, colorFmt, objectTypes[typeNdx], depthStencilFormats[fmtNdx].format);
1691 recreateDepthStencilGroup->addChild(new RecreateBuffersTest(m_context, config, (depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0), true /* rebind */));
1692 }
1693 }
1694 }
1695
1696 } // Functional
1697 } // gles3
1698 } // deqp
1699