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 colorbuffer tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es3fFboColorbufferTests.hpp"
25 #include "es3fFboTestCase.hpp"
26 #include "es3fFboTestUtil.hpp"
27 #include "gluTextureUtil.hpp"
28 #include "gluContextInfo.hpp"
29 #include "tcuImageCompare.hpp"
30 #include "tcuRGBA.hpp"
31 #include "tcuTestLog.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "sglrContextUtil.hpp"
34 #include "deRandom.hpp"
35 #include "deString.h"
36 #include "glwEnums.hpp"
37
38 namespace deqp
39 {
40 namespace gles3
41 {
42 namespace Functional
43 {
44
45 using std::string;
46 using tcu::Vec2;
47 using tcu::Vec3;
48 using tcu::Vec4;
49 using tcu::IVec2;
50 using tcu::IVec3;
51 using tcu::IVec4;
52 using tcu::UVec4;
53 using tcu::TestLog;
54 using namespace FboTestUtil;
55
56 const tcu::RGBA MIN_THRESHOLD(12, 12, 12, 12);
57
58 template <int Size>
59 static tcu::Vector<float, Size> randomVector (de::Random& rnd, const tcu::Vector<float, Size>& minVal = tcu::Vector<float, Size>(0.0f), const tcu::Vector<float, Size>& maxVal = tcu::Vector<float, Size>(1.0f))
60 {
61 tcu::Vector<float, Size> res;
62 for (int ndx = 0; ndx < Size; ndx++)
63 res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
64 return res;
65 }
66
generateRandomColor(de::Random & random)67 static tcu::Vec4 generateRandomColor (de::Random& random)
68 {
69 tcu::Vec4 retVal;
70
71 for (int i = 0; i < 3; ++i)
72 retVal[i] = random.getFloat();
73 retVal[3] = 1.0f;
74
75 return retVal;
76 }
77
78 class FboColorbufferCase : public FboTestCase
79 {
80 public:
FboColorbufferCase(Context & context,const char * name,const char * desc,const deUint32 format)81 FboColorbufferCase (Context& context, const char* name, const char* desc, const deUint32 format)
82 : FboTestCase (context, name, desc)
83 , m_format (format)
84 {
85 }
86
compare(const tcu::Surface & reference,const tcu::Surface & result)87 bool compare (const tcu::Surface& reference, const tcu::Surface& result)
88 {
89 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_format), MIN_THRESHOLD));
90
91 m_testCtx.getLog() << TestLog::Message << "Comparing images, threshold: " << threshold << TestLog::EndMessage;
92
93 return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
94 }
95
96 protected:
97 const deUint32 m_format;
98 };
99
100 class FboColorClearCase : public FboColorbufferCase
101 {
102 public:
FboColorClearCase(Context & context,const char * name,const char * desc,deUint32 format,int width,int height)103 FboColorClearCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height)
104 : FboColorbufferCase (context, name, desc, format)
105 , m_width (width)
106 , m_height (height)
107 {
108 }
109
110 protected:
preCheck(void)111 void preCheck (void)
112 {
113 checkFormatSupport(m_format);
114 }
115
render(tcu::Surface & dst)116 void render (tcu::Surface& dst)
117 {
118 tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format);
119 tcu::TextureChannelClass fmtClass = tcu::getTextureChannelClass(fboFormat.type);
120 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat);
121 de::Random rnd (17);
122 const int numClears = 16;
123 deUint32 fbo = 0;
124 deUint32 rbo = 0;
125
126 glGenFramebuffers(1, &fbo);
127 glGenRenderbuffers(1, &rbo);
128
129 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
130 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_width, m_height);
131 checkError();
132
133 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
134 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
135 checkError();
136 checkFramebufferStatus(GL_FRAMEBUFFER);
137
138 glViewport(0, 0, m_width, m_height);
139
140 // Initialize to transparent black.
141 switch (fmtClass)
142 {
143 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
144 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
145 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
146 glClearBufferfv(GL_COLOR, 0, Vec4(0.0f).getPtr());
147 break;
148
149 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
150 glClearBufferuiv(GL_COLOR, 0, UVec4(0).getPtr());
151 break;
152
153 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
154 glClearBufferiv(GL_COLOR, 0, IVec4(0).getPtr());
155 break;
156
157 default:
158 DE_ASSERT(DE_FALSE);
159 }
160
161 // Do random scissored clears.
162 glEnable(GL_SCISSOR_TEST);
163 for (int ndx = 0; ndx < numClears; ndx++)
164 {
165 int x = rnd.getInt(0, m_width - 1);
166 int y = rnd.getInt(0, m_height - 1);
167 int w = rnd.getInt(1, m_width - x);
168 int h = rnd.getInt(1, m_height - y);
169 Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);
170
171 glScissor(x, y, w, h);
172
173 switch (fmtClass)
174 {
175 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
176 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
177 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
178 glClearBufferfv(GL_COLOR, 0, color.getPtr());
179 break;
180
181 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
182 glClearBufferuiv(GL_COLOR, 0, color.cast<deUint32>().getPtr());
183 break;
184
185 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
186 glClearBufferiv(GL_COLOR, 0, color.cast<int>().getPtr());
187 break;
188
189 default:
190 DE_ASSERT(DE_FALSE);
191 }
192 }
193
194 // Read results from renderbuffer.
195 readPixels(dst, 0, 0, m_width, m_height, fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
196 checkError();
197 }
198
199 private:
200 const int m_width;
201 const int m_height;
202 };
203
204 class FboColorMultiTex2DCase : public FboColorbufferCase
205 {
206 public:
FboColorMultiTex2DCase(Context & context,const char * name,const char * description,deUint32 tex0Fmt,const IVec2 & tex0Size,deUint32 tex1Fmt,const IVec2 & tex1Size)207 FboColorMultiTex2DCase (Context& context, const char* name, const char* description, deUint32 tex0Fmt, const IVec2& tex0Size, deUint32 tex1Fmt, const IVec2& tex1Size)
208 : FboColorbufferCase (context, name, description, tex0Fmt)
209 , m_tex0Fmt (tex0Fmt)
210 , m_tex1Fmt (tex1Fmt)
211 , m_tex0Size (tex0Size)
212 , m_tex1Size (tex1Size)
213 {
214 }
215
216 protected:
preCheck(void)217 void preCheck (void)
218 {
219 checkFormatSupport(m_tex0Fmt);
220 checkFormatSupport(m_tex1Fmt);
221 }
222
render(tcu::Surface & dst)223 void render (tcu::Surface& dst)
224 {
225 tcu::TextureFormat texFmt0 = glu::mapGLInternalFormat(m_tex0Fmt);
226 tcu::TextureFormat texFmt1 = glu::mapGLInternalFormat(m_tex1Fmt);
227 tcu::TextureFormatInfo fmtInfo0 = tcu::getTextureFormatInfo(texFmt0);
228 tcu::TextureFormatInfo fmtInfo1 = tcu::getTextureFormatInfo(texFmt1);
229
230 Texture2DShader texToFbo0Shader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt0), fmtInfo0.valueMax-fmtInfo0.valueMin, fmtInfo0.valueMin);
231 Texture2DShader texToFbo1Shader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt1), fmtInfo1.valueMax-fmtInfo1.valueMin, fmtInfo1.valueMin);
232 Texture2DShader multiTexShader (DataTypes() << glu::getSampler2DType(texFmt0) << glu::getSampler2DType(texFmt1), glu::TYPE_FLOAT_VEC4);
233
234 deUint32 texToFbo0ShaderID = getCurrentContext()->createProgram(&texToFbo0Shader);
235 deUint32 texToFbo1ShaderID = getCurrentContext()->createProgram(&texToFbo1Shader);
236 deUint32 multiTexShaderID = getCurrentContext()->createProgram(&multiTexShader);
237
238 // Setup shaders
239 multiTexShader.setTexScaleBias(0, fmtInfo0.lookupScale * 0.5f, fmtInfo0.lookupBias * 0.5f);
240 multiTexShader.setTexScaleBias(1, fmtInfo1.lookupScale * 0.5f, fmtInfo1.lookupBias * 0.5f);
241 texToFbo0Shader.setUniforms(*getCurrentContext(), texToFbo0ShaderID);
242 texToFbo1Shader.setUniforms(*getCurrentContext(), texToFbo1ShaderID);
243 multiTexShader.setUniforms (*getCurrentContext(), multiTexShaderID);
244
245 // Framebuffers.
246 deUint32 fbo0 = 0;
247 deUint32 fbo1 = 0;
248 deUint32 tex0 = 0;
249 deUint32 tex1 = 0;
250
251 for (int ndx = 0; ndx < 2; ndx++)
252 {
253 glu::TransferFormat transferFmt = glu::getTransferFormat(ndx ? texFmt1 : texFmt0);
254 deUint32 format = ndx ? m_tex1Fmt : m_tex0Fmt;
255 bool isFilterable = glu::isGLInternalColorFormatFilterable(format);
256 const IVec2& size = ndx ? m_tex1Size : m_tex0Size;
257 deUint32& fbo = ndx ? fbo1 : fbo0;
258 deUint32& tex = ndx ? tex1 : tex0;
259
260 glGenFramebuffers(1, &fbo);
261 glGenTextures(1, &tex);
262
263 glBindTexture(GL_TEXTURE_2D, tex);
264 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
265 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
266 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST);
267 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST);
268 glTexImage2D(GL_TEXTURE_2D, 0, format, size.x(), size.y(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
269
270 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
271 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
272 checkError();
273 checkFramebufferStatus(GL_FRAMEBUFFER);
274 }
275
276 // Render textures to both framebuffers.
277 for (int ndx = 0; ndx < 2; ndx++)
278 {
279 const deUint32 format = GL_RGBA;
280 const deUint32 dataType = GL_UNSIGNED_BYTE;
281 const int texW = 128;
282 const int texH = 128;
283 deUint32 tmpTex = 0;
284 deUint32 fbo = ndx ? fbo1 : fbo0;
285 const IVec2& viewport = ndx ? m_tex1Size : m_tex0Size;
286 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1);
287
288 if (ndx == 0)
289 tcu::fillWithComponentGradients(data.getAccess(), Vec4(0.0f), Vec4(1.0f));
290 else
291 tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f));
292
293 glGenTextures(1, &tmpTex);
294 glBindTexture(GL_TEXTURE_2D, tmpTex);
295 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
296 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
297 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
299 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
300
301 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
302 glViewport(0, 0, viewport.x(), viewport.y());
303 sglr::drawQuad(*getCurrentContext(), ndx ? texToFbo1ShaderID : texToFbo0ShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
304 }
305
306 // Render to framebuffer.
307 glBindFramebuffer(GL_FRAMEBUFFER, 0);
308 glViewport(0, 0, getWidth(), getHeight());
309 glActiveTexture(GL_TEXTURE0);
310 glBindTexture(GL_TEXTURE_2D, tex0);
311 glActiveTexture(GL_TEXTURE1);
312 glBindTexture(GL_TEXTURE_2D, tex1);
313 sglr::drawQuad(*getCurrentContext(), multiTexShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
314
315 readPixels(dst, 0, 0, getWidth(), getHeight());
316 }
317
318 private:
319 deUint32 m_tex0Fmt;
320 deUint32 m_tex1Fmt;
321 IVec2 m_tex0Size;
322 IVec2 m_tex1Size;
323 };
324
325 class FboColorTexCubeCase : public FboColorbufferCase
326 {
327 public:
FboColorTexCubeCase(Context & context,const char * name,const char * description,deUint32 texFmt,const IVec2 & texSize)328 FboColorTexCubeCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec2& texSize)
329 : FboColorbufferCase (context, name, description, texFmt)
330 , m_texSize (texSize)
331 {
332 }
333
334 protected:
preCheck(void)335 void preCheck (void)
336 {
337 checkFormatSupport(m_format);
338 }
339
render(tcu::Surface & dst)340 void render (tcu::Surface& dst)
341 {
342 static const deUint32 cubeGLFaces[] =
343 {
344 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
345 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
346 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
347 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
348 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
349 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
350 };
351
352 static const tcu::CubeFace cubeTexFaces[] =
353 {
354 tcu::CUBEFACE_POSITIVE_X,
355 tcu::CUBEFACE_POSITIVE_Y,
356 tcu::CUBEFACE_POSITIVE_Z,
357 tcu::CUBEFACE_NEGATIVE_X,
358 tcu::CUBEFACE_NEGATIVE_Y,
359 tcu::CUBEFACE_NEGATIVE_Z
360 };
361
362 de::Random rnd (deStringHash(getName()) ^ 0x9eef603d);
363 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_format);
364 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
365
366 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin);
367 TextureCubeShader cubeTexShader (glu::getSamplerCubeType(texFmt), glu::TYPE_FLOAT_VEC4);
368
369 deUint32 texToFboShaderID = getCurrentContext()->createProgram(&texToFboShader);
370 deUint32 cubeTexShaderID = getCurrentContext()->createProgram(&cubeTexShader);
371
372 // Setup shaders
373 texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID);
374 cubeTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);
375
376 // Framebuffers.
377 std::vector<deUint32> fbos;
378 deUint32 tex;
379
380 {
381 glu::TransferFormat transferFmt = glu::getTransferFormat(texFmt);
382 bool isFilterable = glu::isGLInternalColorFormatFilterable(m_format);
383 const IVec2& size = m_texSize;
384
385
386 glGenTextures(1, &tex);
387
388 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
389 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
390 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
391 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST);
392 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST);
393
394 // Generate an image and FBO for each cube face
395 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeGLFaces); ndx++)
396 glTexImage2D(cubeGLFaces[ndx], 0, m_format, size.x(), size.y(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
397 checkError();
398
399 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeGLFaces); ndx++)
400 {
401 deUint32 layerFbo;
402
403 glGenFramebuffers(1, &layerFbo);
404 glBindFramebuffer(GL_FRAMEBUFFER, layerFbo);
405 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubeGLFaces[ndx], tex, 0);
406 checkError();
407 checkFramebufferStatus(GL_FRAMEBUFFER);
408
409 fbos.push_back(layerFbo);
410 }
411 }
412
413 // Render test images to random cube faces
414 std::vector<int> order;
415
416 for (size_t n = 0; n < fbos.size(); n++)
417 order.push_back((int)n);
418 rnd.shuffle(order.begin(), order.end());
419
420 DE_ASSERT(order.size() >= 4);
421 for (int ndx = 0; ndx < 4; ndx++)
422 {
423 const int face = order[ndx];
424 const deUint32 format = GL_RGBA;
425 const deUint32 dataType = GL_UNSIGNED_BYTE;
426 const int texW = 128;
427 const int texH = 128;
428 deUint32 tmpTex = 0;
429 const deUint32 fbo = fbos[face];
430 const IVec2& viewport = m_texSize;
431 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1);
432
433 tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f));
434
435 glGenTextures(1, &tmpTex);
436 glBindTexture(GL_TEXTURE_2D, tmpTex);
437 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
438 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
439 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
440 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
441 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
442
443 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
444 glViewport(0, 0, viewport.x(), viewport.y());
445 sglr::drawQuad(*getCurrentContext(), texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
446 checkError();
447
448 // Render to framebuffer
449 {
450 const Vec3 p0 = Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f);
451 const Vec3 p1 = p0 + Vec3(1.0f, 1.0f, 0.0f);
452
453 glBindFramebuffer(GL_FRAMEBUFFER, 0);
454 glViewport(0, 0, getWidth(), getHeight());
455
456 glActiveTexture(GL_TEXTURE0);
457 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
458
459 cubeTexShader.setFace(cubeTexFaces[face]);
460 cubeTexShader.setUniforms(*getCurrentContext(), cubeTexShaderID);
461
462 sglr::drawQuad(*getCurrentContext(), cubeTexShaderID, p0, p1);
463 checkError();
464 }
465 }
466
467 readPixels(dst, 0, 0, getWidth(), getHeight());
468 }
469
470 private:
471 IVec2 m_texSize;
472 };
473
474 class FboColorTex2DArrayCase : public FboColorbufferCase
475 {
476 public:
FboColorTex2DArrayCase(Context & context,const char * name,const char * description,deUint32 texFmt,const IVec3 & texSize)477 FboColorTex2DArrayCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec3& texSize)
478 : FboColorbufferCase (context, name, description, texFmt)
479 , m_texSize (texSize)
480 {
481 }
482
483 protected:
preCheck(void)484 void preCheck (void)
485 {
486 checkFormatSupport(m_format);
487 }
488
render(tcu::Surface & dst)489 void render (tcu::Surface& dst)
490 {
491 de::Random rnd (deStringHash(getName()) ^ 0xed607a89);
492 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_format);
493 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
494
495 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin);
496 Texture2DArrayShader arrayTexShader (glu::getSampler2DArrayType(texFmt), glu::TYPE_FLOAT_VEC4);
497
498 deUint32 texToFboShaderID = getCurrentContext()->createProgram(&texToFboShader);
499 deUint32 arrayTexShaderID = getCurrentContext()->createProgram(&arrayTexShader);
500
501 // Setup textures
502 texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID);
503 arrayTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);
504
505 // Framebuffers.
506 std::vector<deUint32> fbos;
507 deUint32 tex;
508
509 {
510 glu::TransferFormat transferFmt = glu::getTransferFormat(texFmt);
511 bool isFilterable = glu::isGLInternalColorFormatFilterable(m_format);
512 const IVec3& size = m_texSize;
513
514
515 glGenTextures(1, &tex);
516
517 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
518 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
519 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
520 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
521 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST);
522 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, isFilterable ? GL_LINEAR : GL_NEAREST);
523 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, size.x(), size.y(), size.z(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
524
525 // Generate an FBO for each layer
526 for (int ndx = 0; ndx < m_texSize.z(); ndx++)
527 {
528 deUint32 layerFbo;
529
530 glGenFramebuffers(1, &layerFbo);
531 glBindFramebuffer(GL_FRAMEBUFFER, layerFbo);
532 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, ndx);
533 checkError();
534 checkFramebufferStatus(GL_FRAMEBUFFER);
535
536 fbos.push_back(layerFbo);
537 }
538 }
539
540 // Render test images to random texture layers
541 std::vector<int> order;
542
543 for (size_t n = 0; n < fbos.size(); n++)
544 order.push_back((int)n);
545 rnd.shuffle(order.begin(), order.end());
546
547 for (size_t ndx = 0; ndx < order.size(); ndx++)
548 {
549 const int layer = order[ndx];
550 const deUint32 format = GL_RGBA;
551 const deUint32 dataType = GL_UNSIGNED_BYTE;
552 const int texW = 128;
553 const int texH = 128;
554 deUint32 tmpTex = 0;
555 const deUint32 fbo = fbos[layer];
556 const IVec3& viewport = m_texSize;
557 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1);
558
559 tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f));
560
561 glGenTextures(1, &tmpTex);
562 glBindTexture(GL_TEXTURE_2D, tmpTex);
563 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
564 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
566 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
567 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
568
569 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
570 glViewport(0, 0, viewport.x(), viewport.y());
571 sglr::drawQuad(*getCurrentContext(), texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
572 checkError();
573
574 // Render to framebuffer
575 {
576 const Vec3 p0 = Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f);
577 const Vec3 p1 = p0 + Vec3(1.0f, 1.0f, 0.0f);
578
579 glBindFramebuffer(GL_FRAMEBUFFER, 0);
580 glViewport(0, 0, getWidth(), getHeight());
581
582 glActiveTexture(GL_TEXTURE0);
583 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
584
585 arrayTexShader.setLayer(layer);
586 arrayTexShader.setUniforms(*getCurrentContext(), arrayTexShaderID);
587
588 sglr::drawQuad(*getCurrentContext(), arrayTexShaderID, p0, p1);
589 checkError();
590 }
591 }
592
593 readPixels(dst, 0, 0, getWidth(), getHeight());
594 }
595
596 private:
597 IVec3 m_texSize;
598 };
599
600 class FboColorTex3DCase : public FboColorbufferCase
601 {
602 public:
FboColorTex3DCase(Context & context,const char * name,const char * description,deUint32 texFmt,const IVec3 & texSize)603 FboColorTex3DCase (Context& context, const char* name, const char* description, deUint32 texFmt, const IVec3& texSize)
604 : FboColorbufferCase (context, name, description, texFmt)
605 , m_texSize (texSize)
606 {
607 }
608
609 protected:
preCheck(void)610 void preCheck (void)
611 {
612 checkFormatSupport(m_format);
613 }
614
render(tcu::Surface & dst)615 void render (tcu::Surface& dst)
616 {
617 de::Random rnd (deStringHash(getName()) ^ 0x74d947b2);
618 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(m_format);
619 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
620
621 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, getFragmentOutputType(texFmt), fmtInfo.valueMax-fmtInfo.valueMin, fmtInfo.valueMin);
622 Texture3DShader tdTexShader (glu::getSampler3DType(texFmt), glu::TYPE_FLOAT_VEC4);
623
624 deUint32 texToFboShaderID= getCurrentContext()->createProgram(&texToFboShader);
625 deUint32 tdTexShaderID = getCurrentContext()->createProgram(&tdTexShader);
626
627 // Setup shaders
628 texToFboShader.setUniforms(*getCurrentContext(), texToFboShaderID);
629 tdTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);
630
631 // Framebuffers.
632 std::vector<deUint32> fbos;
633 deUint32 tex;
634
635 {
636 glu::TransferFormat transferFmt = glu::getTransferFormat(texFmt);
637 const IVec3& size = m_texSize;
638
639 glGenTextures(1, &tex);
640
641 glBindTexture(GL_TEXTURE_3D, tex);
642 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
643 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
644 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
645 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
646 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
647 glTexImage3D(GL_TEXTURE_3D, 0, m_format, size.x(), size.y(), size.z(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
648
649 // Generate an FBO for each layer
650 for (int ndx = 0; ndx < m_texSize.z(); ndx++)
651 {
652 deUint32 layerFbo;
653
654 glGenFramebuffers(1, &layerFbo);
655 glBindFramebuffer(GL_FRAMEBUFFER, layerFbo);
656 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, ndx);
657 checkError();
658 checkFramebufferStatus(GL_FRAMEBUFFER);
659
660 fbos.push_back(layerFbo);
661 }
662 }
663
664 // Render test images to random texture layers
665 std::vector<int> order;
666
667 for (size_t n = 0; n < fbos.size(); n++)
668 order.push_back((int)n);
669 rnd.shuffle(order.begin(), order.end());
670
671 for (size_t ndx = 0; ndx < order.size(); ndx++)
672 {
673 const int layer = order[ndx];
674 const deUint32 format = GL_RGBA;
675 const deUint32 dataType = GL_UNSIGNED_BYTE;
676 const int texW = 128;
677 const int texH = 128;
678 deUint32 tmpTex = 0;
679 const deUint32 fbo = fbos[layer];
680 const IVec3& viewport = m_texSize;
681 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1);
682
683 tcu::fillWithGrid(data.getAccess(), 8, generateRandomColor(rnd), Vec4(0.0f));
684
685 glGenTextures(1, &tmpTex);
686 glBindTexture(GL_TEXTURE_2D, tmpTex);
687 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
688 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
689 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
690 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
691 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
692
693 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
694 glViewport(0, 0, viewport.x(), viewport.y());
695 sglr::drawQuad(*getCurrentContext() , texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
696 checkError();
697
698 // Render to framebuffer
699 {
700 const Vec3 p0 = Vec3(float(ndx % 2) - 1.0f, float(ndx / 2) - 1.0f, 0.0f);
701 const Vec3 p1 = p0 + Vec3(1.0f, 1.0f, 0.0f);
702
703 glBindFramebuffer(GL_FRAMEBUFFER, 0);
704 glViewport(0, 0, getWidth(), getHeight());
705
706 glActiveTexture(GL_TEXTURE0);
707 glBindTexture(GL_TEXTURE_3D, tex);
708
709 tdTexShader.setDepth(float(layer) / float(m_texSize.z()-1));
710 tdTexShader.setUniforms(*getCurrentContext(), tdTexShaderID);
711
712 sglr::drawQuad(*getCurrentContext(), tdTexShaderID, p0, p1);
713 checkError();
714 }
715 }
716
717 readPixels(dst, 0, 0, getWidth(), getHeight());
718 }
719
720 private:
721 IVec3 m_texSize;
722 };
723
724 class FboBlendCase : public FboColorbufferCase
725 {
726 public:
FboBlendCase(Context & context,const char * name,const char * desc,deUint32 format,IVec2 size,deUint32 funcRGB,deUint32 funcAlpha,deUint32 srcRGB,deUint32 dstRGB,deUint32 srcAlpha,deUint32 dstAlpha)727 FboBlendCase (Context& context, const char* name, const char* desc, deUint32 format, IVec2 size, deUint32 funcRGB, deUint32 funcAlpha, deUint32 srcRGB, deUint32 dstRGB, deUint32 srcAlpha, deUint32 dstAlpha)
728 : FboColorbufferCase (context, name, desc, format)
729 , m_size (size)
730 , m_funcRGB (funcRGB)
731 , m_funcAlpha (funcAlpha)
732 , m_srcRGB (srcRGB)
733 , m_dstRGB (dstRGB)
734 , m_srcAlpha (srcAlpha)
735 , m_dstAlpha (dstAlpha)
736 {
737 }
738
739 protected:
preCheck(void)740 void preCheck (void)
741 {
742 checkFormatSupport(m_format);
743 }
744
render(tcu::Surface & dst)745 void render (tcu::Surface& dst)
746 {
747 // \note Assumes floating-point or fixed-point format.
748 tcu::TextureFormat fboFmt = glu::mapGLInternalFormat(m_format);
749 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
750 GradientShader gradShader (glu::TYPE_FLOAT_VEC4);
751 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader);
752 deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader);
753 deUint32 fbo = 0;
754 deUint32 rbo = 0;
755
756 // Setup shaders
757 texShader.setUniforms (*getCurrentContext(), texShaderID);
758 gradShader.setGradient(*getCurrentContext(), gradShaderID, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
759
760 glGenFramebuffers(1, &fbo);
761 glGenRenderbuffers(1, &rbo);
762
763 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
764 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_size.x(), m_size.y());
765 checkError();
766
767 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
768 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
769 checkError();
770 checkFramebufferStatus(GL_FRAMEBUFFER);
771
772 glViewport(0, 0, m_size.x(), m_size.y());
773
774 // Fill framebuffer with grid pattern.
775 {
776 const deUint32 format = GL_RGBA;
777 const deUint32 dataType = GL_UNSIGNED_BYTE;
778 const int texW = 128;
779 const int texH = 128;
780 deUint32 gridTex = 0;
781 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1);
782
783 tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f));
784
785 glGenTextures(1, &gridTex);
786 glBindTexture(GL_TEXTURE_2D, gridTex);
787 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
788 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
789 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
791 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
792
793 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
794 }
795
796 // Setup blend.
797 glEnable(GL_BLEND);
798 glBlendEquationSeparate(m_funcRGB, m_funcAlpha);
799 glBlendFuncSeparate(m_srcRGB, m_dstRGB, m_srcAlpha, m_dstAlpha);
800
801 // Render gradient with blend.
802 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
803
804 readPixels(dst, 0, 0, m_size.x(), m_size.y(), fboFmt, Vec4(1.0f), Vec4(0.0f));
805 }
806
807 private:
808 IVec2 m_size;
809 deUint32 m_funcRGB;
810 deUint32 m_funcAlpha;
811 deUint32 m_srcRGB;
812 deUint32 m_dstRGB;
813 deUint32 m_srcAlpha;
814 deUint32 m_dstAlpha;
815 };
816
817 class FboRepeatedClearSampleTex2DCase : public FboColorbufferCase
818 {
819 public:
FboRepeatedClearSampleTex2DCase(Context & context,const char * name,const char * desc,deUint32 format)820 FboRepeatedClearSampleTex2DCase (Context& context, const char* name, const char* desc, deUint32 format)
821 : FboColorbufferCase(context, name, desc, format)
822 {
823 }
824
825 protected:
preCheck(void)826 void preCheck (void)
827 {
828 checkFormatSupport(m_format);
829 }
830
render(tcu::Surface & dst)831 void render (tcu::Surface& dst)
832 {
833 const tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format);
834 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat);
835 const int numRowsCols = 4;
836 const int cellSize = 16;
837 const int fboSizes[] = { cellSize, cellSize*numRowsCols };
838
839 Texture2DShader fboBlitShader (DataTypes() << glu::getSampler2DType(fboFormat), getFragmentOutputType(fboFormat), Vec4(1.0f), Vec4(0.0f));
840 const deUint32 fboBlitShaderID = getCurrentContext()->createProgram(&fboBlitShader);
841
842 de::Random rnd (18169662);
843 deUint32 fbos[] = { 0, 0 };
844 deUint32 textures[] = { 0, 0 };
845
846 glGenFramebuffers(2, &fbos[0]);
847 glGenTextures(2, &textures[0]);
848
849 for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++)
850 {
851 glBindTexture(GL_TEXTURE_2D, textures[fboNdx]);
852 glTexStorage2D(GL_TEXTURE_2D, 1, m_format, fboSizes[fboNdx], fboSizes[fboNdx]);
853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
854 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
855 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
857 checkError();
858
859 glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]);
860 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0);
861 checkError();
862 checkFramebufferStatus(GL_FRAMEBUFFER);
863 }
864
865 // larger fbo bound -- clear to transparent black
866 clearColorBuffer(fboFormat, Vec4(0.0f));
867
868 fboBlitShader.setUniforms(*getCurrentContext(), fboBlitShaderID);
869 glBindTexture(GL_TEXTURE_2D, textures[0]);
870
871 for (int cellY = 0; cellY < numRowsCols; cellY++)
872 for (int cellX = 0; cellX < numRowsCols; cellX++)
873 {
874 const Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);
875
876 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
877 clearColorBuffer(fboFormat, color);
878
879 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
880 glViewport(cellX*cellSize, cellY*cellSize, cellSize, cellSize);
881 sglr::drawQuad(*getCurrentContext(), fboBlitShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
882 }
883
884 readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
885 checkError();
886 }
887 };
888
889 class FboRepeatedClearBlitTex2DCase : public FboColorbufferCase
890 {
891 public:
FboRepeatedClearBlitTex2DCase(Context & context,const char * name,const char * desc,deUint32 format)892 FboRepeatedClearBlitTex2DCase (Context& context, const char* name, const char* desc, deUint32 format)
893 : FboColorbufferCase(context, name, desc, format)
894 {
895 }
896
897 protected:
preCheck(void)898 void preCheck (void)
899 {
900 checkFormatSupport(m_format);
901 }
902
render(tcu::Surface & dst)903 void render (tcu::Surface& dst)
904 {
905 const tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format);
906 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat);
907 const int numRowsCols = 4;
908 const int cellSize = 16;
909 const int fboSizes[] = { cellSize, cellSize*numRowsCols };
910
911 de::Random rnd (18169662);
912 deUint32 fbos[] = { 0, 0 };
913 deUint32 textures[] = { 0, 0 };
914
915 glGenFramebuffers(2, &fbos[0]);
916 glGenTextures(2, &textures[0]);
917
918 for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++)
919 {
920 glBindTexture(GL_TEXTURE_2D, textures[fboNdx]);
921 glTexStorage2D(GL_TEXTURE_2D, 1, m_format, fboSizes[fboNdx], fboSizes[fboNdx]);
922 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
923 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
924 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
925 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
926 checkError();
927
928 glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]);
929 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[fboNdx], 0);
930 checkError();
931 checkFramebufferStatus(GL_FRAMEBUFFER);
932 }
933
934 // larger fbo bound -- clear to transparent black
935 clearColorBuffer(fboFormat, Vec4(0.0f));
936
937 for (int cellY = 0; cellY < numRowsCols; cellY++)
938 for (int cellX = 0; cellX < numRowsCols; cellX++)
939 {
940 const Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);
941
942 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
943 clearColorBuffer(fboFormat, color);
944
945 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
946 glBlitFramebuffer(0, 0, cellSize, cellSize, cellX*cellSize, cellY*cellSize, (cellX+1)*cellSize, (cellY+1)*cellSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
947 }
948
949 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
950 readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
951 checkError();
952 }
953 };
954
955 class FboRepeatedClearBlitRboCase : public FboColorbufferCase
956 {
957 public:
FboRepeatedClearBlitRboCase(Context & context,const char * name,const char * desc,deUint32 format)958 FboRepeatedClearBlitRboCase (Context& context, const char* name, const char* desc, deUint32 format)
959 : FboColorbufferCase(context, name, desc, format)
960 {
961 }
962
963 protected:
preCheck(void)964 void preCheck (void)
965 {
966 checkFormatSupport(m_format);
967 }
968
render(tcu::Surface & dst)969 void render (tcu::Surface& dst)
970 {
971 const tcu::TextureFormat fboFormat = glu::mapGLInternalFormat(m_format);
972 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(fboFormat);
973 const int numRowsCols = 4;
974 const int cellSize = 16;
975 const int fboSizes[] = { cellSize, cellSize*numRowsCols };
976
977 de::Random rnd (18169662);
978 deUint32 fbos[] = { 0, 0 };
979 deUint32 rbos[] = { 0, 0 };
980
981 glGenFramebuffers(2, &fbos[0]);
982 glGenRenderbuffers(2, &rbos[0]);
983
984 for (int fboNdx = 0; fboNdx < DE_LENGTH_OF_ARRAY(fbos); fboNdx++)
985 {
986 glBindRenderbuffer(GL_RENDERBUFFER, rbos[fboNdx]);
987 glRenderbufferStorage(GL_RENDERBUFFER, m_format, fboSizes[fboNdx], fboSizes[fboNdx]);
988 checkError();
989
990 glBindFramebuffer(GL_FRAMEBUFFER, fbos[fboNdx]);
991 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbos[fboNdx]);
992 checkError();
993 checkFramebufferStatus(GL_FRAMEBUFFER);
994 }
995
996 // larger fbo bound -- clear to transparent black
997 clearColorBuffer(fboFormat, Vec4(0.0f));
998
999 for (int cellY = 0; cellY < numRowsCols; cellY++)
1000 for (int cellX = 0; cellX < numRowsCols; cellX++)
1001 {
1002 const Vec4 color = randomVector<4>(rnd, fmtInfo.valueMin, fmtInfo.valueMax);
1003
1004 glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
1005 clearColorBuffer(fboFormat, color);
1006
1007 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
1008 glBlitFramebuffer(0, 0, cellSize, cellSize, cellX*cellSize, cellY*cellSize, (cellX+1)*cellSize, (cellY+1)*cellSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1009 }
1010
1011 glBindFramebuffer(GL_FRAMEBUFFER, fbos[1]);
1012 readPixels(dst, 0, 0, fboSizes[1], fboSizes[1], fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
1013 checkError();
1014 }
1015 };
1016
FboColorTests(Context & context)1017 FboColorTests::FboColorTests (Context& context)
1018 : TestCaseGroup(context, "color", "Colorbuffer tests")
1019 {
1020 }
1021
~FboColorTests(void)1022 FboColorTests::~FboColorTests (void)
1023 {
1024 }
1025
init(void)1026 void FboColorTests::init (void)
1027 {
1028 static const deUint32 colorFormats[] =
1029 {
1030 // RGBA formats
1031 GL_RGBA32I,
1032 GL_RGBA32UI,
1033 GL_RGBA16I,
1034 GL_RGBA16UI,
1035 GL_RGBA8,
1036 GL_RGBA8I,
1037 GL_RGBA8UI,
1038 GL_SRGB8_ALPHA8,
1039 GL_RGB10_A2,
1040 GL_RGB10_A2UI,
1041 GL_RGBA4,
1042 GL_RGB5_A1,
1043
1044 // RGB formats
1045 GL_RGB8,
1046 GL_RGB565,
1047
1048 // RG formats
1049 GL_RG32I,
1050 GL_RG32UI,
1051 GL_RG16I,
1052 GL_RG16UI,
1053 GL_RG8,
1054 GL_RG8I,
1055 GL_RG8UI,
1056
1057 // R formats
1058 GL_R32I,
1059 GL_R32UI,
1060 GL_R16I,
1061 GL_R16UI,
1062 GL_R8,
1063 GL_R8I,
1064 GL_R8UI,
1065
1066 // GL_EXT_color_buffer_float
1067 GL_RGBA32F,
1068 GL_RGBA16F,
1069 GL_R11F_G11F_B10F,
1070 GL_RG32F,
1071 GL_RG16F,
1072 GL_R32F,
1073 GL_R16F,
1074
1075 // GL_EXT_color_buffer_half_float
1076 GL_RGB16F
1077 };
1078
1079 // .clear
1080 {
1081 tcu::TestCaseGroup* clearGroup = new tcu::TestCaseGroup(m_testCtx, "clear", "Color clears");
1082 addChild(clearGroup);
1083
1084 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
1085 clearGroup->addChild(new FboColorClearCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], 129, 117));
1086 }
1087
1088 // .tex2d
1089 {
1090 tcu::TestCaseGroup* tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "Texture 2D tests");
1091 addChild(tex2DGroup);
1092
1093 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1094 tex2DGroup->addChild(new FboColorMultiTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
1095 colorFormats[fmtNdx], IVec2(129, 117),
1096 colorFormats[fmtNdx], IVec2(99, 128)));
1097 }
1098
1099 // .texcube
1100 {
1101 tcu::TestCaseGroup* texCubeGroup = new tcu::TestCaseGroup(m_testCtx, "texcube", "Texture cube map tests");
1102 addChild(texCubeGroup);
1103
1104 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1105 texCubeGroup->addChild(new FboColorTexCubeCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
1106 colorFormats[fmtNdx], IVec2(128, 128)));
1107 }
1108
1109 // .tex2darray
1110 {
1111 tcu::TestCaseGroup* tex2DArrayGroup = new tcu::TestCaseGroup(m_testCtx, "tex2darray", "Texture 2D array tests");
1112 addChild(tex2DArrayGroup);
1113
1114 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1115 tex2DArrayGroup->addChild(new FboColorTex2DArrayCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
1116 colorFormats[fmtNdx], IVec3(128, 128, 5)));
1117 }
1118
1119 // .tex3d
1120 {
1121 tcu::TestCaseGroup* tex3DGroup = new tcu::TestCaseGroup(m_testCtx, "tex3d", "Texture 3D tests");
1122 addChild(tex3DGroup);
1123
1124 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1125 tex3DGroup->addChild(new FboColorTex3DCase(m_context, getFormatName(colorFormats[fmtNdx]), "",
1126 colorFormats[fmtNdx], IVec3(128, 128, 5)));
1127 }
1128
1129 // .blend
1130 {
1131 tcu::TestCaseGroup* blendGroup = new tcu::TestCaseGroup(m_testCtx, "blend", "Blending tests");
1132 addChild(blendGroup);
1133
1134 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1135 {
1136 deUint32 format = colorFormats[fmtNdx];
1137 tcu::TextureFormat texFmt = glu::mapGLInternalFormat(format);
1138 tcu::TextureChannelClass fmtClass = tcu::getTextureChannelClass(texFmt.type);
1139 string fmtName = getFormatName(format);
1140
1141 if (texFmt.type == tcu::TextureFormat::FLOAT ||
1142 fmtClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
1143 fmtClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
1144 continue; // Blending is not supported.
1145
1146 blendGroup->addChild(new FboBlendCase(m_context, (fmtName + "_src_over").c_str(), "", format, IVec2(127, 111), GL_FUNC_ADD, GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE));
1147 }
1148 }
1149
1150 // .repeated_clear
1151 {
1152 tcu::TestCaseGroup* const repeatedClearGroup = new tcu::TestCaseGroup(m_testCtx, "repeated_clear", "Repeated clears and blits");
1153 addChild(repeatedClearGroup);
1154
1155 // .sample.tex2d
1156 {
1157 tcu::TestCaseGroup* const sampleGroup = new tcu::TestCaseGroup(m_testCtx, "sample", "Read by sampling");
1158 repeatedClearGroup->addChild(sampleGroup);
1159
1160 tcu::TestCaseGroup* const tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "2D Texture");
1161 sampleGroup->addChild(tex2DGroup);
1162
1163 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1164 tex2DGroup->addChild(new FboRepeatedClearSampleTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]),
1165 "", colorFormats[fmtNdx]));
1166 }
1167
1168 // .blit
1169 {
1170 tcu::TestCaseGroup* const blitGroup = new tcu::TestCaseGroup(m_testCtx, "blit", "Blitted");
1171 repeatedClearGroup->addChild(blitGroup);
1172
1173 // .tex2d
1174 {
1175 tcu::TestCaseGroup* const tex2DGroup = new tcu::TestCaseGroup(m_testCtx, "tex2d", "2D Texture");
1176 blitGroup->addChild(tex2DGroup);
1177
1178 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1179 tex2DGroup->addChild(new FboRepeatedClearBlitTex2DCase(m_context, getFormatName(colorFormats[fmtNdx]),
1180 "", colorFormats[fmtNdx]));
1181 }
1182
1183 // .rbo
1184 {
1185 tcu::TestCaseGroup* const rboGroup = new tcu::TestCaseGroup(m_testCtx, "rbo", "Renderbuffer");
1186 blitGroup->addChild(rboGroup);
1187
1188 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); fmtNdx++)
1189 rboGroup->addChild(new FboRepeatedClearBlitRboCase(m_context, getFormatName(colorFormats[fmtNdx]),
1190 "", colorFormats[fmtNdx]));
1191 }
1192 }
1193 }
1194 }
1195
1196 } // Functional
1197 } // gles3
1198 } // deqp
1199