1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2017 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 EXT Shader Framebuffer Fetch Tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fShaderFramebufferFetchTests.hpp"
25 #include "es31fFboTestUtil.hpp"
26
27 #include "tcuTestLog.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuTextureUtil.hpp"
30 #include "tcuImageCompare.hpp"
31 #include "tcuVectorUtil.hpp"
32
33 #include "gluShaderProgram.hpp"
34 #include "gluPixelTransfer.hpp"
35 #include "gluTextureUtil.hpp"
36 #include "gluContextInfo.hpp"
37 #include "gluObjectWrapper.hpp"
38
39 #include "glwFunctions.hpp"
40 #include "glwEnums.hpp"
41
42 #include "deStringUtil.hpp"
43
44 #include <vector>
45
46 namespace deqp
47 {
48 namespace gles31
49 {
50 namespace Functional
51 {
52 namespace
53 {
54
55 using std::vector;
56 using std::string;
57 using tcu::TestLog;
58
59 using namespace glw;
60 using namespace FboTestUtil;
61
checkExtensionSupport(Context & context,const char * extName)62 static void checkExtensionSupport (Context& context, const char* extName)
63 {
64 if (!context.getContextInfo().isExtensionSupported(extName))
65 throw tcu::NotSupportedError(string(extName) + " not supported");
66 }
67
checkFramebufferFetchSupport(Context & context)68 static void checkFramebufferFetchSupport (Context& context)
69 {
70 checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch");
71 }
72
isRequiredFormat(deUint32 format,glu::RenderContext & renderContext)73 static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
74 {
75 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
76 switch (format)
77 {
78 // Color-renderable formats
79 case GL_RGBA32I:
80 case GL_RGBA32UI:
81 case GL_RGBA16I:
82 case GL_RGBA16UI:
83 case GL_RGBA8:
84 case GL_RGBA8I:
85 case GL_RGBA8UI:
86 case GL_SRGB8_ALPHA8:
87 case GL_RGB10_A2:
88 case GL_RGB10_A2UI:
89 case GL_RGBA4:
90 case GL_RGB5_A1:
91 case GL_RGB8:
92 case GL_RGB565:
93 case GL_RG32I:
94 case GL_RG32UI:
95 case GL_RG16I:
96 case GL_RG16UI:
97 case GL_RG8:
98 case GL_RG8I:
99 case GL_RG8UI:
100 case GL_R32I:
101 case GL_R32UI:
102 case GL_R16I:
103 case GL_R16UI:
104 case GL_R8:
105 case GL_R8I:
106 case GL_R8UI:
107 return true;
108
109 // Float format
110 case GL_RGBA32F:
111 case GL_RGB32F:
112 case GL_R11F_G11F_B10F:
113 case GL_RG32F:
114 case GL_R32F:
115 return isES32;
116
117 default:
118 return false;
119 }
120 }
121
getReadPixelFormat(const tcu::TextureFormat & format)122 tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
123 {
124 switch (tcu::getTextureChannelClass(format.type))
125 {
126 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
127 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
128
129 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
130 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
131
132 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
133 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
134 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
135
136 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
137 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
138
139 default:
140 DE_ASSERT(false);
141 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
142 }
143 }
144
getFixedPointFormatThreshold(const tcu::TextureFormat & sourceFormat,const tcu::TextureFormat & readPixelsFormat)145 tcu::Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
146 {
147 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
148 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
149
150 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
151 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
152
153 DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
154 DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
155
156 const tcu::IVec4 srcBits = tcu::getTextureFormatBitDepth(sourceFormat);
157 const tcu::IVec4 readBits = tcu::getTextureFormatBitDepth(readPixelsFormat);
158
159 return tcu::Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>();
160 }
161
getFloatULPThreshold(const tcu::TextureFormat & sourceFormat,const tcu::TextureFormat & readPixelsFormat)162 tcu::UVec4 getFloatULPThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
163 {
164 const tcu::IVec4 srcMantissaBits = tcu::getTextureFormatMantissaBitDepth(sourceFormat);
165 const tcu::IVec4 readMantissaBits = tcu::getTextureFormatMantissaBitDepth(readPixelsFormat);
166 tcu::IVec4 ULPDiff(0);
167
168 for (int i = 0; i < 4; i++)
169 if (readMantissaBits[i] >= srcMantissaBits[i])
170 ULPDiff[i] = readMantissaBits[i] - srcMantissaBits[i];
171
172 return tcu::UVec4(4) * (tcu::UVec4(1) << (ULPDiff.cast<deUint32>()));
173 }
174
isAnyExtensionSupported(Context & context,const std::vector<std::string> & requiredExts)175 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
176 {
177 for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
178 {
179 const std::string& extension = *iter;
180
181 if (context.getContextInfo().isExtensionSupported(extension.c_str()))
182 return true;
183 }
184
185 return false;
186 }
187
getColorOutputType(tcu::TextureFormat format)188 static std::string getColorOutputType(tcu::TextureFormat format)
189 {
190 switch (tcu::getTextureChannelClass(format.type))
191 {
192 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: return "uvec4";
193 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: return "ivec4";
194 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
195 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
196 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: return "vec4";
197 default:
198 DE_FATAL("Unsupported TEXTURECHANNELCLASS");
199 return "";
200 }
201 }
202
getEnablingExtensions(deUint32 format,glu::RenderContext & renderContext)203 static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
204 {
205 const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
206 std::vector<std::string> out;
207
208 DE_ASSERT(!isRequiredFormat(format, renderContext));
209
210 switch (format)
211 {
212 case GL_RGB16F:
213 out.push_back("GL_EXT_color_buffer_half_float");
214 break;
215
216 case GL_RGBA16F:
217 case GL_RG16F:
218 case GL_R16F:
219 out.push_back("GL_EXT_color_buffer_half_float");
220 // Fallthrough
221
222 case GL_RGBA32F:
223 case GL_RGB32F:
224 case GL_R11F_G11F_B10F:
225 case GL_RG32F:
226 case GL_R32F:
227 if (!isES32)
228 out.push_back("GL_EXT_color_buffer_float");
229 break;
230
231 default:
232 break;
233 }
234
235 return out;
236 }
237
checkFormatSupport(Context & context,deUint32 sizedFormat)238 void checkFormatSupport (Context& context, deUint32 sizedFormat)
239 {
240 const bool isCoreFormat = isRequiredFormat(sizedFormat, context.getRenderContext());
241 const std::vector<std::string> requiredExts = (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>();
242
243 // Check that we don't try to use invalid formats.
244 DE_ASSERT(isCoreFormat || !requiredExts.empty());
245
246 if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts))
247 throw tcu::NotSupportedError("Format not supported");
248 }
249
scaleColorValue(tcu::TextureFormat format,const tcu::Vec4 & color)250 tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color)
251 {
252 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(format);
253 const tcu::Vec4 cScale = fmtInfo.valueMax-fmtInfo.valueMin;
254 const tcu::Vec4 cBias = fmtInfo.valueMin;
255
256 return tcu::RGBA(color).toVec() * cScale + cBias;
257 }
258
259 // Base class for framebuffer fetch test cases
260
261 class FramebufferFetchTestCase : public TestCase
262 {
263 public:
264 FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
265 ~FramebufferFetchTestCase (void);
266
267 void init (void);
268 void deinit (void);
269
270 protected:
271 string genPassThroughVertSource (void);
272 virtual glu::ProgramSources genShaderSources (void);
273
274 void genFramebufferWithTexture (const tcu::Vec4& color);
275 void genAttachementTexture (const tcu::Vec4& color);
276 void genUniformColor (const tcu::Vec4& color);
277
278 void render (void);
279 void verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result);
280
281 const glw::Functions& m_gl;
282 const deUint32 m_format;
283
284 glu::ShaderProgram* m_program;
285 GLuint m_framebuffer;
286 GLuint m_texColorBuffer;
287
288 tcu::TextureFormat m_texFmt;
289 glu::TransferFormat m_transferFmt;
290 bool m_isFilterable;
291
292 enum
293 {
294 VIEWPORT_WIDTH = 64,
295 VIEWPORT_HEIGHT = 64,
296 };
297 };
298
FramebufferFetchTestCase(Context & context,const char * name,const char * desc,deUint32 format)299 FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
300 : TestCase (context, name, desc)
301 , m_gl (m_context.getRenderContext().getFunctions())
302 , m_format (format)
303 , m_program (DE_NULL)
304 , m_framebuffer (0)
305 , m_texColorBuffer (0)
306 , m_texFmt (glu::mapGLInternalFormat(m_format))
307 , m_transferFmt (glu::getTransferFormat(m_texFmt))
308 , m_isFilterable (glu::isGLInternalColorFormatFilterable(m_format))
309 {
310 }
311
~FramebufferFetchTestCase(void)312 FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
313 {
314 FramebufferFetchTestCase::deinit();
315 }
316
init(void)317 void FramebufferFetchTestCase::init (void)
318 {
319 checkFramebufferFetchSupport (m_context);
320 checkFormatSupport(m_context, m_format);
321
322 DE_ASSERT(!m_program);
323 m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources());
324
325 m_testCtx.getLog() << *m_program;
326
327 if (!m_program->isOk())
328 {
329 delete m_program;
330 m_program = DE_NULL;
331 TCU_FAIL("Failed to compile shader program");
332 }
333
334 m_gl.useProgram(m_program->getProgram());
335 }
336
deinit(void)337 void FramebufferFetchTestCase::deinit (void)
338 {
339 delete m_program;
340 m_program = DE_NULL;
341
342 if (m_framebuffer)
343 {
344 m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
345 m_gl.deleteFramebuffers(1, &m_framebuffer);
346 m_framebuffer = 0;
347 }
348
349 if (m_texColorBuffer)
350 {
351 m_gl.deleteTextures(1, &m_texColorBuffer);
352 m_texColorBuffer = 0;
353 }
354 }
355
genPassThroughVertSource(void)356 string FramebufferFetchTestCase::genPassThroughVertSource (void)
357 {
358 std::ostringstream vertShaderSource;
359
360 vertShaderSource << "#version 310 es\n"
361 << "in highp vec4 a_position;\n"
362 << "\n"
363 << "void main (void)\n"
364 << "{\n"
365 << " gl_Position = a_position;\n"
366 << "}\n";
367
368 return vertShaderSource.str();
369 }
370
genShaderSources(void)371 glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
372 {
373 const string vecType = getColorOutputType(m_texFmt);
374 std::ostringstream fragShaderSource;
375
376 fragShaderSource << "#version 310 es\n"
377 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
378 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
379 << "uniform highp " << vecType << " u_color;\n"
380 << "\n"
381 << "void main (void)\n"
382 << "{\n"
383 << " o_color += u_color;\n"
384 << "}\n";
385
386 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
387 }
388
genFramebufferWithTexture(const tcu::Vec4 & color)389 void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color)
390 {
391 m_gl.genFramebuffers(1, &m_framebuffer);
392 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
393
394 genAttachementTexture(color);
395 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()");
396
397 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
398 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
399 }
400
genAttachementTexture(const tcu::Vec4 & color)401 void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color)
402 {
403 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
404 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
405
406 m_gl.genTextures(1, &m_texColorBuffer);
407 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
408
409 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
410 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
411 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
412 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
413 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
414
415 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
416 tcu::clear(data.getAccess(), color.asUint());
417 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
418 tcu::clear(data.getAccess(), color.asInt());
419 else
420 tcu::clear(data.getAccess(), color);
421
422 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
423 m_gl.bindTexture(GL_TEXTURE_2D, 0);
424 }
425
verifyRenderbuffer(TestLog & log,const tcu::TextureFormat & format,const tcu::TextureLevel & reference,const tcu::TextureLevel & result)426 void FramebufferFetchTestCase::verifyRenderbuffer (TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result)
427 {
428 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
429
430 switch (tcu::getTextureChannelClass(format.type))
431 {
432 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
433 {
434 const string name = "Renderbuffer";
435 const string desc = "Compare renderbuffer (floating_point)";
436 const tcu::UVec4 threshold = getFloatULPThreshold(format, result.getFormat());
437
438 if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
439 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
440
441 break;
442 }
443
444 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
445 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
446 {
447 const string name = "Renderbuffer";
448 const string desc = "Compare renderbuffer (integer)";
449 const tcu::UVec4 threshold (1, 1, 1, 1);
450
451 if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
452 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
453
454 break;
455 }
456
457 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
458 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
459 {
460 const string name = "Renderbuffer";
461 const string desc = "Compare renderbuffer (fixed point)";
462 const tcu::Vec4 threshold = getFixedPointFormatThreshold(format, result.getFormat());
463
464 if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
465 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
466
467 break;
468 }
469
470 default:
471 {
472 DE_ASSERT(DE_FALSE);
473 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
474 }
475 }
476 }
477
genUniformColor(const tcu::Vec4 & color)478 void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color)
479 {
480 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_color");
481
482 switch (tcu::getTextureChannelClass(m_texFmt.type))
483 {
484 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
485 {
486 m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr());
487 break;
488 }
489
490 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
491 {
492 m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr());
493 break;
494 }
495 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
496 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
497 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
498 {
499 m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr());
500 break;
501 }
502 default:
503 DE_ASSERT(DE_FALSE);
504 }
505
506 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()");
507 }
508
render(void)509 void FramebufferFetchTestCase::render (void)
510 {
511 const GLfloat coords[] =
512 {
513 -1.0f, -1.0f,
514 +1.0f, -1.0f,
515 +1.0f, +1.0f,
516 -1.0f, +1.0f,
517 };
518
519 const GLushort indices[] =
520 {
521 0, 1, 2, 2, 3, 0,
522 };
523
524 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
525
526 m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
527
528 glu::Buffer coordinatesBuffer(m_context.getRenderContext());
529 glu::Buffer elementsBuffer(m_context.getRenderContext());
530
531 m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer);
532 m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
533 m_gl.enableVertexAttribArray(coordLocation);
534 m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
535
536 m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer);
537 m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW);
538
539 m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
540 GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()");
541 }
542
543 // Test description:
544 // - Attach texture containing solid color to framebuffer.
545 // - Draw full quad covering the entire viewport.
546 // - Sum framebuffer read color with passed in uniform color.
547 // - Compare resulting surface with reference.
548
549 class TextureFormatTestCase : public FramebufferFetchTestCase
550 {
551 public:
552 TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format);
~TextureFormatTestCase(void)553 ~TextureFormatTestCase (void) {};
554
555 IterateResult iterate (void);
556
557 private:
558 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
559 };
560
TextureFormatTestCase(Context & context,const char * name,const char * desc,deUint32 format)561 TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
562 : FramebufferFetchTestCase(context, name, desc, format)
563 {
564 }
565
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)566 tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
567 {
568 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
569 tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
570
571 if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
572 {
573 tcu::clear(reference.getAccess(), fbColor.asUint() + uniformColor.asUint());
574 }
575 else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
576 {
577 tcu::clear(reference.getAccess(), fbColor.asInt() + uniformColor.asInt());
578 }
579 else
580 {
581 if (tcu::isSRGB(m_texFmt))
582 {
583 const tcu::Vec4 fragmentColor = tcu::sRGBToLinear(fbColor) + uniformColor;
584 tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
585 }
586 else
587 {
588 tcu::clear(reference.getAccess(), fbColor + uniformColor);
589 }
590 }
591
592 return reference;
593 }
594
iterate(void)595 TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
596 {
597 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
598 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
599
600 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
601 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
602
603 genFramebufferWithTexture(fbColor);
604 genUniformColor(uniformColor);
605 render();
606
607 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
608 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
609
610 return STOP;
611 }
612
613 // Test description:
614 // - Attach multiple textures containing solid colors to framebuffer.
615 // - Draw full quad covering the entire viewport.
616 // - For each render target sum framebuffer read color with passed in uniform color.
617 // - Compare resulting surfaces with references.
618
619 class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
620 {
621 public:
622 MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format);
623 ~MultipleRenderTargetsTestCase (void);
624
625 IterateResult iterate (void);
626 void deinit (void);
627
628 private:
629 void genFramebufferWithTextures (const vector<tcu::Vec4>& colors);
630 void genAttachmentTextures (const vector<tcu::Vec4>& colors);
631 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
632 glu::ProgramSources genShaderSources (void);
633
634 enum
635 {
636 MAX_COLOR_BUFFERS = 4
637 };
638
639 GLuint m_texColorBuffers [MAX_COLOR_BUFFERS];
640 GLenum m_colorBuffers [MAX_COLOR_BUFFERS];
641 };
642
MultipleRenderTargetsTestCase(Context & context,const char * name,const char * desc,deUint32 format)643 MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
644 : FramebufferFetchTestCase(context, name, desc, format)
645 , m_texColorBuffers ()
646 {
647 m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
648 m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
649 m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
650 m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
651 }
652
~MultipleRenderTargetsTestCase(void)653 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
654 {
655 MultipleRenderTargetsTestCase::deinit();
656 }
657
deinit(void)658 void MultipleRenderTargetsTestCase::deinit (void)
659 {
660 // Clean up texture data
661 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
662 {
663 if (m_texColorBuffers[i])
664 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
665 }
666
667 FramebufferFetchTestCase::deinit();
668 }
669
genFramebufferWithTextures(const vector<tcu::Vec4> & colors)670 void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
671 {
672 m_gl.genFramebuffers(1, &m_framebuffer);
673 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
674
675 genAttachmentTextures(colors);
676
677 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
678 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
679
680 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
681
682 m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
683 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
684 }
685
genAttachmentTextures(const vector<tcu::Vec4> & colors)686 void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
687 {
688 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
689
690 m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
691
692 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
693 {
694 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
695
696 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
697 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
698 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
699 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
700 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isFilterable ? GL_LINEAR : GL_NEAREST);
701
702 clear(data.getAccess(), colors[i]);
703 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
704 }
705
706 m_gl.bindTexture(GL_TEXTURE_2D, 0);
707 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
708 }
709
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)710 tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
711 {
712 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
713 tcu::clear(reference.getAccess(), fbColor + uniformColor);
714
715 return reference;
716 }
717
genShaderSources(void)718 glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
719 {
720 const string vecType = getColorOutputType(m_texFmt);
721 std::ostringstream fragShaderSource;
722
723 fragShaderSource << "#version 310 es\n"
724 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
725 << "layout(location = 0) inout highp " << vecType << " o_color0;\n"
726 << "layout(location = 1) inout highp " << vecType << " o_color1;\n"
727 << "layout(location = 2) inout highp " << vecType << " o_color2;\n"
728 << "layout(location = 3) inout highp " << vecType << " o_color3;\n"
729 << "uniform highp " << vecType << " u_color;\n"
730 << "\n"
731 << "void main (void)\n"
732 << "{\n"
733 << " o_color0 += u_color;\n"
734 << " o_color1 += u_color;\n"
735 << " o_color2 += u_color;\n"
736 << " o_color3 += u_color;\n"
737 << "}\n";
738
739 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
740 }
741
iterate(void)742 MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
743 {
744 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
745 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
746
747 vector<tcu::Vec4> colors;
748 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
749 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
750 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
751 colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
752
753 genFramebufferWithTextures(colors);
754 genUniformColor(uniformColor);
755 render();
756
757 for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
758 {
759 tcu::TextureLevel reference = genReferenceTexture(colors[i], uniformColor);
760
761 m_gl.readBuffer(m_colorBuffers[i]);
762 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
763 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
764 }
765
766 return STOP;
767 }
768
769 // Test description:
770 // - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
771
772 class LastFragDataTestCase : public FramebufferFetchTestCase
773 {
774 public:
775 LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format);
~LastFragDataTestCase(void)776 ~LastFragDataTestCase (void) {};
777
778 IterateResult iterate (void);
779
780 private:
781 glu::ProgramSources genShaderSources (void);
782 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
783 };
784
LastFragDataTestCase(Context & context,const char * name,const char * desc,deUint32 format)785 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
786 : FramebufferFetchTestCase(context, name, desc, format)
787 {
788 }
789
genShaderSources(void)790 glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
791 {
792 const string vecType = getColorOutputType(m_texFmt);
793 std::ostringstream vertShaderSource;
794 std::ostringstream fragShaderSource;
795
796 vertShaderSource << "#version 100\n"
797 << "attribute vec4 a_position;\n"
798 << "\n"
799 << "void main (void)\n"
800 << "{\n"
801 << " gl_Position = a_position;\n"
802 << "}\n";
803
804 fragShaderSource << "#version 100\n"
805 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
806 << "uniform highp " << vecType << " u_color;\n"
807 << "\n"
808 << "void main (void)\n"
809 << "{\n"
810 << " gl_FragColor = u_color + gl_LastFragData[0];\n"
811 << "}\n";
812
813 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
814 }
815
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)816 tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
817 {
818 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
819 tcu::clear(reference.getAccess(), fbColor + uniformColor);
820
821 return reference;
822 }
823
iterate(void)824 LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
825 {
826 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
827 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
828
829 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
830 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
831
832 genFramebufferWithTexture(fbColor);
833 genUniformColor(uniformColor);
834 render();
835
836 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
837 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
838
839 return STOP;
840 }
841
842 // Test description:
843 // - Attach texture containing solid color to framebuffer.
844 // - Create one 2D texture for sampler with a grid pattern
845 // - Draw full screen quad covering the entire viewport.
846 // - Sum color values taken from framebuffer texture and sampled texture
847 // - Compare resulting surface with reference.
848
849 class TexelFetchTestCase : public FramebufferFetchTestCase
850 {
851 public:
852 TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format);
~TexelFetchTestCase(void)853 ~TexelFetchTestCase (void) {}
854
855 IterateResult iterate (void);
856
857 private:
858 glu::ProgramSources genShaderSources (void);
859 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
860 void genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
861
862 GLuint m_samplerTexture;
863 };
864
TexelFetchTestCase(Context & context,const char * name,const char * desc,deUint32 format)865 TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
866 : FramebufferFetchTestCase(context, name, desc, format)
867 , m_samplerTexture(0)
868 {
869 }
870
genSamplerTexture(const tcu::Vec4 & colorEven,const tcu::Vec4 & colorOdd)871 void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
872 {
873 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
874
875 m_gl.activeTexture(GL_TEXTURE1);
876
877 m_gl.genTextures(1, &m_samplerTexture);
878 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
879 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
880 m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
881
882 tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
883
884 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
885 m_gl.bindTexture(GL_TEXTURE_2D, 0);
886
887 const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
888 m_gl.uniform1i(samplerLocation, 1);
889
890 GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
891 }
892
genShaderSources(void)893 glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
894 {
895 const string vecType = getColorOutputType(m_texFmt);
896 std::ostringstream fragShaderSource;
897
898 fragShaderSource << "#version 310 es\n"
899 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
900 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
901 << "\n"
902 << "uniform sampler2D u_sampler;\n"
903 << "void main (void)\n"
904 << "{\n"
905 << " o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
906 << "}\n";
907
908 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
909 }
910
genReferenceTexture(const tcu::Vec4 & colorEven,const tcu::Vec4 & colorOdd,const tcu::Vec4 & fbColor)911 tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
912 {
913 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
914 tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
915
916 return reference;
917 }
918
iterate(void)919 TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
920 {
921 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
922 const tcu::Vec4 colorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
923 const tcu::Vec4 colorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
924
925 genSamplerTexture(colorEven, colorOdd);
926 tcu::TextureLevel reference = genReferenceTexture(colorEven, colorOdd, fbColor);
927 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
928
929 genFramebufferWithTexture(fbColor);
930 render();
931
932 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
933 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
934
935 // cleanup
936 m_gl.deleteTextures(1, &m_samplerTexture);
937
938 return STOP;
939 }
940
941 // Test description:
942 // - Attach texture containing solid color to framebuffer.
943 // - Draw full screen quad covering the entire viewport.
944 // - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
945 // - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
946 // - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
947 // - Compare resulting surface with reference.
948
949 class MultipleAssignmentTestCase : public FramebufferFetchTestCase
950 {
951 public:
952 MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format);
~MultipleAssignmentTestCase(void)953 ~MultipleAssignmentTestCase (void) {}
954
955 IterateResult iterate (void);
956
957 private:
958 glu::ProgramSources genShaderSources (void);
959 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
960 };
961
MultipleAssignmentTestCase(Context & context,const char * name,const char * desc,deUint32 format)962 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
963 : FramebufferFetchTestCase(context, name, desc, format)
964 {
965 }
966
genShaderSources(void)967 glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
968 {
969 const string vecType = getColorOutputType(m_texFmt);
970 std::ostringstream vertShaderSource;
971 std::ostringstream fragShaderSource;
972
973 vertShaderSource << "#version 310 es\n"
974 << "in highp vec4 a_position;\n"
975 << "out highp vec4 v_position;\n"
976 << "\n"
977 << "void main (void)\n"
978 << "{\n"
979 << " gl_Position = a_position;\n"
980 << " v_position = gl_Position;\n"
981 << "}\n";
982
983 fragShaderSource << "#version 310 es\n"
984 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
985 << "in highp vec4 v_position;\n"
986 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
987 << "uniform highp " << vecType << " u_color;\n"
988 << "\n"
989 << "void main (void)\n"
990 << "{\n"
991 << " if (v_position.x > 0.0f)\n"
992 << " o_color += u_color;\n"
993 << "\n"
994 << " o_color += u_color;\n"
995 << "}\n";
996
997 return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
998 }
999
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)1000 tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
1001 {
1002 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1003
1004 int width = reference.getAccess().getWidth();
1005 int height = reference.getAccess().getHeight();
1006 int left = width /2;
1007 int top = height/2;
1008
1009 tcu::Vec4 compositeColor(uniformColor * 2.0f);
1010
1011 tcu::clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), fbColor + compositeColor);
1012 tcu::clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), fbColor + uniformColor);
1013 tcu::clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), fbColor + compositeColor);
1014 tcu::clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), fbColor + uniformColor);
1015
1016 return reference;
1017 }
1018
iterate(void)1019 MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
1020 {
1021 const tcu::Vec4 fbColor = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
1022 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
1023
1024 tcu::TextureLevel reference = genReferenceTexture(fbColor, uniformColor);
1025 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1026
1027 genFramebufferWithTexture(fbColor);
1028 genUniformColor(uniformColor);
1029 render();
1030
1031 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1032 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1033
1034 return STOP;
1035 }
1036
1037 // Test description:
1038 // - Attach texture containing grid pattern to framebuffer.
1039 // - Using framebuffer reads discard odd squares in the grid.
1040 // - The even squares framebuffer color is added to the passed in uniform color.
1041
1042 class FragmentDiscardTestCase : public FramebufferFetchTestCase
1043 {
1044 public:
1045 FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format);
~FragmentDiscardTestCase(void)1046 ~FragmentDiscardTestCase (void) {}
1047
1048 IterateResult iterate (void);
1049
1050 private:
1051 glu::ProgramSources genShaderSources (void);
1052 void genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1053 tcu::TextureLevel genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1054 };
1055
FragmentDiscardTestCase(Context & context,const char * name,const char * desc,deUint32 format)1056 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1057 : FramebufferFetchTestCase(context, name, desc, format)
1058 {
1059 }
1060
genShaderSources(void)1061 glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
1062 {
1063 const string vecType = getColorOutputType(m_texFmt);
1064 std::ostringstream fragShaderSource;
1065
1066 fragShaderSource << "#version 310 es\n"
1067 << "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1068 << "layout(location = 0) inout highp " << vecType << " o_color;\n"
1069 << "uniform highp " << vecType << " u_color;\n"
1070 << "\n"
1071 << "void main (void)\n"
1072 << "{\n"
1073 << " const highp float threshold = 0.0005f;\n"
1074 << " bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
1075 << " if (valuesEqual)\n"
1076 << " o_color += u_color;\n"
1077 << " else\n"
1078 << " discard;\n"
1079 << "}\n";
1080
1081 return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
1082 }
1083
genFramebufferWithGrid(const tcu::Vec4 & fbColorEven,const tcu::Vec4 & fbColorOdd)1084 void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1085 {
1086 tcu::TextureLevel data (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1087
1088 m_gl.genFramebuffers(1, &m_framebuffer);
1089 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1090
1091 m_gl.genTextures(1, &m_texColorBuffer);
1092 m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
1093
1094 tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
1095
1096 m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
1097 m_gl.bindTexture(GL_TEXTURE_2D, 0);
1098
1099 m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
1100 TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1101 }
1102
genReferenceTexture(const tcu::Vec4 & fbColorEven,const tcu::Vec4 & fbColorOdd)1103 tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1104 {
1105 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1106 tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
1107
1108 return reference;
1109 }
1110
iterate(void)1111 FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
1112 {
1113 const tcu::Vec4 fbColorEven = scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
1114 const tcu::Vec4 fbColorOdd = scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
1115
1116 tcu::TextureLevel reference = genReferenceTexture(fbColorEven, fbColorOdd);
1117 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1118 genFramebufferWithGrid(fbColorEven, fbColorOdd);
1119
1120 genUniformColor(fbColorEven);
1121 render();
1122
1123 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1124 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1125
1126 return STOP;
1127 }
1128
1129 // Test description:
1130 // - Create 2D texture array containing three mipmaps.
1131 // - Each mipmap level is assigned a different color.
1132 // - Attach single mipmap level to framebuffer and draw full screen quad.
1133 // - Sum framebuffer read color with passed in uniform color.
1134 // - Compare resulting surface with reference.
1135 // - Repeat for subsequent mipmap levels.
1136
1137 class TextureLevelTestCase : public FramebufferFetchTestCase
1138 {
1139 public:
1140 TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format);
~TextureLevelTestCase(void)1141 ~TextureLevelTestCase (void) {}
1142
1143 IterateResult iterate (void);
1144
1145 private:
1146 void create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors);
1147 tcu::TextureLevel genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1148 void genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference);
1149 };
1150
TextureLevelTestCase(Context & context,const char * name,const char * desc,deUint32 format)1151 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1152 : FramebufferFetchTestCase(context, name, desc, format)
1153 {
1154 }
1155
create2DTextureArrayMipMaps(const vector<tcu::Vec4> & colors)1156 void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
1157 {
1158 int numLevels = (int)colors.size();
1159 tcu::TextureLevel levelData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1160
1161 m_gl.genTextures(1, &m_texColorBuffer);
1162 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1163
1164 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
1165 m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
1166
1167 for (int level = 0; level < numLevels; level++)
1168 {
1169 int levelW = de::max(1, VIEWPORT_WIDTH >> level);
1170 int levelH = de::max(1, VIEWPORT_HEIGHT >> level);
1171
1172 levelData.setSize(levelW, levelH, 1);
1173
1174 clear(levelData.getAccess(), colors[level]);
1175 m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
1176 }
1177
1178 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1179 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
1180 }
1181
genReferenceTexture(int level,const vector<tcu::Vec4> & colors,const tcu::Vec4 & uniformColor)1182 tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1183 {
1184 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
1185
1186 genReferenceMipmap(colors[level] + uniformColor, reference);
1187
1188 return reference;
1189 }
1190
genReferenceMipmap(const tcu::Vec4 & color,tcu::TextureLevel & reference)1191 void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
1192 {
1193 const int width = reference.getAccess().getWidth();
1194 const int height = reference.getAccess().getHeight();
1195 const int left = width / 2;
1196 const int top = height / 2;
1197
1198 clear(getSubregion(reference.getAccess(), left, 0, 0, width-left, top, 1), color);
1199 clear(getSubregion(reference.getAccess(), 0, top, 0, left, height-top, 1), color);
1200 clear(getSubregion(reference.getAccess(), left, top, 0, width-left, height-top, 1), color);
1201 clear(getSubregion(reference.getAccess(), 0, 0, 0, left, top, 1), color);
1202 }
1203
iterate(void)1204 TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
1205 {
1206 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
1207 vector<tcu::Vec4> levelColors;
1208
1209 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1210 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1211 levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1212
1213 m_gl.genFramebuffers(1, &m_framebuffer);
1214 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1215
1216 create2DTextureArrayMipMaps(levelColors);
1217
1218 // attach successive mipmap layers to framebuffer and render
1219 for (int level = 0; level < (int)levelColors.size(); ++level)
1220 {
1221 std::ostringstream name, desc;
1222 name << "Level " << level;
1223 desc << "Mipmap level " << level;
1224
1225 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
1226 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
1227 tcu::TextureLevel reference = genReferenceTexture(level, levelColors, uniformColor);
1228
1229 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
1230
1231 genUniformColor(uniformColor);
1232 render();
1233
1234 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1235 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1236
1237 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1238 return STOP;
1239 }
1240
1241 return STOP;
1242 }
1243
1244 class TextureLayerTestCase : public FramebufferFetchTestCase
1245 {
1246 public:
1247 TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format);
~TextureLayerTestCase(void)1248 ~TextureLayerTestCase (void) {}
1249
1250 IterateResult iterate (void);
1251
1252 private:
1253 void create2DTextureArrayLayers (const vector<tcu::Vec4>& colors);
1254 tcu::TextureLevel genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1255 };
1256
TextureLayerTestCase(Context & context,const char * name,const char * desc,deUint32 format)1257 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1258 : FramebufferFetchTestCase(context, name, desc, format)
1259 {
1260 }
1261
create2DTextureArrayLayers(const vector<tcu::Vec4> & colors)1262 void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
1263 {
1264 int numLayers = (int)colors.size();
1265 tcu::TextureLevel layerData (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1266
1267 m_gl.genTextures(1, &m_texColorBuffer);
1268 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1269 m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1270 m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
1271
1272 layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1273
1274 for (int layer = 0; layer < numLayers; layer++)
1275 {
1276 clear(layerData.getAccess(), colors[layer]);
1277 m_gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, m_transferFmt.format, m_transferFmt.dataType, layerData.getAccess().getDataPtr());
1278 }
1279
1280 m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1281 GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
1282 }
1283
genReferenceTexture(int layer,const vector<tcu::Vec4> & colors,const tcu::Vec4 & uniformColor)1284 tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1285 {
1286 tcu::TextureLevel reference (glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1287 clear(reference.getAccess(), colors[layer] + uniformColor);
1288
1289 return reference;
1290 }
1291
1292 // Test description
1293 // - Create 2D texture array containing three layers.
1294 // - Each layer is assigned a different color.
1295 // - Attach single layer to framebuffer and draw full screen quad.
1296 // - Sum framebuffer read color with passed in uniform color.
1297 // - Compare resulting surface with reference.
1298 // - Repeat for subsequent texture layers.
1299
iterate(void)1300 TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
1301 {
1302 const tcu::Vec4 uniformColor = scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
1303 tcu::TextureLevel result (getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1304 vector<tcu::Vec4> layerColors;
1305
1306 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1307 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1308 layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1309
1310 m_gl.genFramebuffers(1, &m_framebuffer);
1311 m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1312
1313 create2DTextureArrayLayers(layerColors);
1314
1315 for (int layer = 0; layer < (int)layerColors.size(); ++layer)
1316 {
1317 std::ostringstream name, desc;
1318 name << "Layer " << layer;
1319 desc << "Layer " << layer;
1320
1321 const tcu::ScopedLogSection section (m_testCtx.getLog(), name.str(), desc.str());
1322 tcu::TextureLevel reference = genReferenceTexture(layer, layerColors, uniformColor);
1323
1324 m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
1325
1326 genUniformColor(uniformColor);
1327 render();
1328
1329 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1330 verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1331
1332 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1333 return STOP;
1334 }
1335
1336 return STOP;
1337 }
1338
1339 } // Anonymous
1340
ShaderFramebufferFetchTests(Context & context)1341 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
1342 : TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
1343 {
1344 }
1345
~ShaderFramebufferFetchTests(void)1346 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
1347 {
1348 }
1349
init(void)1350 void ShaderFramebufferFetchTests::init (void)
1351 {
1352 tcu::TestCaseGroup* const basicTestGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic framebuffer shader fetch tests");
1353 tcu::TestCaseGroup* const framebufferFormatTestGroup = new tcu::TestCaseGroup(m_testCtx, "framebuffer_format", "Texture render target formats tests");
1354
1355 // basic
1356 {
1357 basicTestGroup->addChild(new TexelFetchTestCase (m_context, "texel_fetch", "Framebuffer fetches in conjunction with shader texel fetches", GL_RGBA8));
1358 basicTestGroup->addChild(new LastFragDataTestCase (m_context, "last_frag_data", "Framebuffer fetches with built-in fragment output of ES 2.0", GL_RGBA8));
1359 basicTestGroup->addChild(new FragmentDiscardTestCase (m_context, "fragment_discard", "Framebuffer fetches in combination with fragment discards", GL_RGBA8));
1360 basicTestGroup->addChild(new MultipleAssignmentTestCase (m_context, "multiple_assignment", "Multiple assignments to fragment color inout", GL_RGBA8));
1361 basicTestGroup->addChild(new MultipleRenderTargetsTestCase (m_context, "multiple_render_targets", "Framebuffer fetches used in combination with multiple render targets", GL_RGBA8));
1362 basicTestGroup->addChild(new TextureLevelTestCase (m_context, "framebuffer_texture_level", "Framebuffer fetches with individual texture render target mipmaps", GL_RGBA8));
1363 basicTestGroup->addChild(new TextureLayerTestCase (m_context, "framebuffer_texture_layer", "Framebuffer fetches with individual texture render target layers", GL_RGBA8));
1364 }
1365
1366 // framebuffer formats
1367 {
1368 static const deUint32 colorFormats[] =
1369 {
1370 // RGBA formats
1371 GL_RGBA32I,
1372 GL_RGBA32UI,
1373 GL_RGBA16I,
1374 GL_RGBA16UI,
1375 GL_RGBA8,
1376 GL_RGBA8I,
1377 GL_RGBA8UI,
1378 GL_SRGB8_ALPHA8,
1379 GL_RGB10_A2,
1380 GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
1381
1382 // RGB formats
1383 GL_RGB8,
1384 GL_RGB565,
1385
1386 // RG formats
1387 GL_RG32I,
1388 GL_RG32UI,
1389 GL_RG16I,
1390 GL_RG16UI,
1391 GL_RG8,
1392 GL_RG8I,
1393 GL_RG8UI,
1394
1395 // R formats
1396 GL_R32I,
1397 GL_R32UI,
1398 GL_R16I,
1399 GL_R16UI,
1400 GL_R8,
1401 GL_R8I,
1402 GL_R8UI,
1403
1404 // GL_EXT_color_buffer_float
1405 GL_RGBA32F,
1406 GL_RGBA16F,
1407 GL_R11F_G11F_B10F,
1408 GL_RG32F,
1409 GL_RG16F,
1410 GL_R32F,
1411 GL_R16F,
1412
1413 // GL_EXT_color_buffer_half_float
1414 GL_RGB16F
1415 };
1416
1417 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
1418 framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
1419 }
1420
1421 addChild(basicTestGroup);
1422 addChild(framebufferFormatTestGroup);
1423 }
1424
1425 } // Functional
1426 } // gles31
1427 } // deqp
1428