1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL (ES) Module
3 * -----------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Framebuffer completeness tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es3fFboCompletenessTests.hpp"
26 #include "glsFboCompletenessTests.hpp"
30 using deqp::gls::Range;
31 using namespace deqp::gls::FboUtil;
32 using namespace deqp::gls::FboUtil::config;
33 namespace fboc = deqp::gls::fboc;
34 typedef tcu::TestCase::IterateResult IterateResult;
36 using std::ostringstream;
45 static const FormatKey s_es3ColorRenderables[] =
47 // GLES3, 4.4.4: "An internal format is color-renderable if it is one of
48 // the formats from table 3.12 noted as color-renderable..."
49 GL_R8, GL_RG8, GL_RGB8, GL_RGB565, GL_RGBA4, GL_RGB5_A1, GL_RGBA8,
50 GL_RGB10_A2, GL_RGB10_A2UI, GL_SRGB8_ALPHA8,
51 GL_R8I, GL_R8UI, GL_R16I, GL_R16UI, GL_R32I, GL_R32UI,
52 GL_RG8I, GL_RG8UI, GL_RG16I, GL_RG16UI, GL_RG32I, GL_RG32UI,
53 GL_RGBA8I, GL_RGBA8UI, GL_RGBA16I, GL_RGBA16UI, GL_RGBA32I, GL_RGBA32UI,
56 static const FormatKey s_es3UnsizedColorRenderables[] =
58 // "...or if it is unsized format RGBA or RGB."
59 // See Table 3.3 in GLES3.
60 GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_BYTE),
61 GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4),
62 GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1),
63 GLS_UNSIZED_FORMATKEY(GL_RGB, GL_UNSIGNED_BYTE),
64 GLS_UNSIZED_FORMATKEY(GL_RGB, GL_UNSIGNED_SHORT_5_6_5),
67 static const FormatKey s_es3DepthRenderables[] =
69 // GLES3, 4.4.4: "An internal format is depth-renderable if it is one of
70 // the formats from table 3.13."
71 GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32F,
72 GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8,
75 static const FormatKey s_es3StencilRboRenderables[] =
77 // GLES3, 4.4.4: "An internal format is stencil-renderable if it is
82 static const FormatKey s_es3StencilRenderables[] =
84 // "...or one of the formats from table 3.13 whose base internal format is
86 GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8,
89 static const FormatKey s_es3TextureFloatFormats[] =
91 GL_RGBA32F, GL_RGBA16F, GL_R11F_G11F_B10F,
92 GL_RG32F, GL_RG16F, GL_R32F, GL_R16F,
93 GL_RGBA16F, GL_RGB16F, GL_RG16F, GL_R16F,
96 static const FormatKey s_es3NotRenderableTextureFormats[] =
98 GL_R8_SNORM, GL_RG8_SNORM, GL_RGB8_SNORM, GL_RGBA8_SNORM,
100 GL_RGB8I, GL_RGB16I, GL_RGB32I,
101 GL_RGB8UI, GL_RGB16UI,GL_RGB32UI,
104 static const FormatEntry s_es3Formats[] =
106 // Renderbuffers don't support unsized formats
107 { REQUIRED_RENDERABLE | COLOR_RENDERABLE | TEXTURE_VALID,
108 GLS_ARRAY_RANGE(s_es3UnsizedColorRenderables) },
109 { REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID,
110 GLS_ARRAY_RANGE(s_es3ColorRenderables) },
111 { REQUIRED_RENDERABLE | DEPTH_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID,
112 GLS_ARRAY_RANGE(s_es3DepthRenderables) },
113 { REQUIRED_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID,
114 GLS_ARRAY_RANGE(s_es3StencilRboRenderables) },
115 { REQUIRED_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID,
116 GLS_ARRAY_RANGE(s_es3StencilRenderables) },
118 GLS_ARRAY_RANGE(s_es3NotRenderableTextureFormats) },
120 // These are not color-renderable in vanilla ES3, but we need to mark them
121 // as valid for textures, since EXT_color_buffer_(half_)float brings in
122 // color-renderability and only renderbuffer-validity.
124 GLS_ARRAY_RANGE(s_es3TextureFloatFormats) },
127 // GL_EXT_color_buffer_float
128 static const FormatKey s_extColorBufferFloatFormats[] =
130 GL_RGBA32F, GL_RGBA16F, GL_R11F_G11F_B10F, GL_RG32F, GL_RG16F, GL_R32F, GL_R16F,
133 // GL_OES_texture_stencil8
134 static const FormatKey s_extOESTextureStencil8[] =
139 // GL_EXT_render_snorm
140 static const FormatKey s_extRenderSnorm[] =
142 GL_R8_SNORM, GL_RG8_SNORM, GL_RGBA8_SNORM,
145 static const FormatExtEntry s_es3ExtFormats[] =
148 "GL_EXT_color_buffer_float",
149 // These are already texture-valid in ES3, the extension just adds RBO
150 // support and makes them color-renderable.
151 (deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID),
152 GLS_ARRAY_RANGE(s_extColorBufferFloatFormats)
155 "GL_OES_texture_stencil8",
156 // \note: es3 RBO tests actually cover the first two requirements
157 // - kept here for completeness
158 (deUint32)(REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID),
159 GLS_ARRAY_RANGE(s_extOESTextureStencil8)
162 // Since GLES31 is backwards compatible to GLES3, we might actually be running on a GLES31.
163 // Add rule changes of GLES31 that have no corresponding GLES3 extension.
165 // \note Not all feature changes are listed here but only those that alter GLES3 subset of
168 "DEQP_gles31_core_compatible GL_EXT_render_snorm",
169 (deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | TEXTURE_VALID | RENDERBUFFER_VALID),
170 GLS_ARRAY_RANGE(s_extRenderSnorm)
174 class ES3Checker : public Checker
177 ES3Checker (const glu::RenderContext& ctx)
180 , m_depthStencilImage (0)
181 , m_depthStencilType (GL_NONE) {}
182 void check (GLenum attPoint, const Attachment& att, const Image* image);
185 //! The common number of samples of images.
186 GLsizei m_numSamples;
188 //! The common image for depth and stencil attachments.
189 GLuint m_depthStencilImage;
190 GLenum m_depthStencilType;
193 void ES3Checker::check (GLenum attPoint, const Attachment& att, const Image* image)
195 GLsizei imgSamples = imageNumSamples(*image);
197 if (m_numSamples == -1)
199 m_numSamples = imgSamples;
203 // GLES3: "The value of RENDERBUFFER_SAMPLES is the same for all attached
204 // renderbuffers and, if the attached images are a mix of renderbuffers
205 // and textures, the value of RENDERBUFFER_SAMPLES is zero."
207 // On creating a renderbuffer: "If _samples_ is zero, then
208 // RENDERBUFFER_SAMPLES is set to zero. Otherwise [...] the resulting
209 // value for RENDERBUFFER_SAMPLES is guaranteed to be greater than or
210 // equal to _samples_ and no more than the next larger sample count
211 // supported by the implementation."
213 // Either all attachments are zero-sample renderbuffers and/or
214 // textures, or none of them are.
215 if ((m_numSamples == 0) != (imgSamples == 0))
216 addFBOStatus(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, "Mixed multi- and single-sampled attachments");
218 // If the attachments requested a different number of samples, the
219 // implementation is allowed to report this as incomplete. However, it
220 // is also possible that despite the different requests, the
221 // implementation allocated the same number of samples to both. Hence
222 // reporting the framebuffer as complete is also legal.
223 if (m_numSamples != imgSamples)
224 addPotentialFBOStatus(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, "Number of samples differ");
227 // "Depth and stencil attachments, if present, are the same image."
228 if (attPoint == GL_DEPTH_ATTACHMENT || attPoint == GL_STENCIL_ATTACHMENT)
230 if (m_depthStencilImage == 0)
232 m_depthStencilImage = att.imageName;
233 m_depthStencilType = attachmentType(att);
237 if (m_depthStencilImage != att.imageName || m_depthStencilType != attachmentType(att))
238 addFBOStatus(GL_FRAMEBUFFER_UNSUPPORTED, "Depth and stencil attachments are not the same image");
243 struct NumLayersParams
245 GLenum textureKind; //< GL_TEXTURE_3D or GL_TEXTURE_2D_ARRAY
246 GLsizei numLayers; //< Number of layers in texture
247 GLsizei attachmentLayer; //< Layer referenced by attachment
249 static string getName (const NumLayersParams& params);
250 static string getDescription (const NumLayersParams& params);
253 string NumLayersParams::getName (const NumLayersParams& params)
256 const string kindStr = params.textureKind == GL_TEXTURE_3D ? "3d" : "2darr";
257 os << kindStr << "_" << params.numLayers << "_" << params.attachmentLayer;
261 string NumLayersParams::getDescription (const NumLayersParams& params)
264 const string kindStr = (params.textureKind == GL_TEXTURE_3D
266 : "2D Array Texture");
268 << params.numLayers << " layers, "
269 << "attached layer " << params.attachmentLayer << ".";
273 class NumLayersTest : public fboc::ParamTest<NumLayersParams>
276 NumLayersTest (fboc::Context& ctx, NumLayersParams param)
277 : fboc::ParamTest<NumLayersParams> (ctx, param) {}
279 IterateResult build (FboBuilder& builder);
282 IterateResult NumLayersTest::build (FboBuilder& builder)
284 TextureLayered* texCfg = DE_NULL;
285 const GLenum target = GL_COLOR_ATTACHMENT0;
287 switch (m_params.textureKind)
290 texCfg = &builder.makeConfig<Texture3D>();
292 case GL_TEXTURE_2D_ARRAY:
293 texCfg = &builder.makeConfig<Texture2DArray>();
296 DE_FATAL("Impossible case");
298 texCfg->internalFormat = getDefaultFormat(target, GL_TEXTURE);
301 texCfg->numLayers = m_params.numLayers;
302 const GLuint tex = builder.glCreateTexture(*texCfg);
304 TextureLayerAttachment* att = &builder.makeConfig<TextureLayerAttachment>();
305 att->layer = m_params.attachmentLayer;
306 att->imageName = tex;
308 builder.glAttach(target, att);
318 struct NumSamplesParams
320 // >= 0: renderbuffer with N samples, -1: texture, -2: no attachment
321 GLsizei numSamples[3];
323 static string getName (const NumSamplesParams& params);
324 static string getDescription (const NumSamplesParams& params);
327 string NumSamplesParams::getName (const NumSamplesParams& params)
331 for (const GLsizei* ns = DE_ARRAY_BEGIN(params.numSamples);
332 ns != DE_ARRAY_END(params.numSamples);
340 if (*ns == SAMPLES_NONE)
342 else if (*ns == SAMPLES_TEXTURE)
350 string NumSamplesParams::getDescription (const NumSamplesParams& params)
354 static const char* const s_names[] = { "color", "depth", "stencil" };
355 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == DE_LENGTH_OF_ARRAY(params.numSamples));
357 for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_names); i++)
359 GLsizei ns = params.numSamples[i];
361 if (ns == SAMPLES_NONE)
369 if (ns == SAMPLES_TEXTURE)
370 os << "texture " << s_names[i] << " attachment";
372 os << ns << "-sample renderbuffer " << s_names[i] << " attachment";
377 class NumSamplesTest : public fboc::ParamTest<NumSamplesParams>
380 NumSamplesTest (fboc::Context& ctx, NumSamplesParams param)
381 : fboc::ParamTest<NumSamplesParams> (ctx, param) {}
383 IterateResult build (FboBuilder& builder);
386 IterateResult NumSamplesTest::build (FboBuilder& builder)
388 static const GLenum s_targets[] =
390 GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_DEPTH_ATTACHMENT,
392 // Non-integer formats for each attachment type.
393 // \todo [2013-12-17 lauri] Add fixed/floating/integer metadata for formats so
394 // we can pick one smartly or maybe try several.
395 static const GLenum s_formats[] =
397 GL_RGBA8, GL_RGB565, GL_DEPTH_COMPONENT24,
399 DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_targets) == DE_LENGTH_OF_ARRAY(m_params.numSamples));
401 for (int i = 0; i < DE_LENGTH_OF_ARRAY(s_targets); i++)
403 const GLenum target = s_targets[i];
404 const ImageFormat fmt = { s_formats[i], GL_NONE };
406 const GLsizei ns = m_params.numSamples[i];
412 attachTargetToNew(target, GL_TEXTURE, fmt, 64, 64, builder);
416 Renderbuffer& rboCfg = builder.makeConfig<Renderbuffer>();
417 rboCfg.internalFormat = fmt;
418 rboCfg.width = rboCfg.height = 64;
419 rboCfg.numSamples = ns;
421 const GLuint rbo = builder.glCreateRbo(rboCfg);
422 // Implementations do not necessarily support sample sizes greater than 1.
423 TCU_CHECK_AND_THROW(NotSupportedError,
424 builder.getError() != GL_INVALID_OPERATION,
425 "Unsupported number of samples");
426 RenderbufferAttachment& att = builder.makeConfig<RenderbufferAttachment>();
428 builder.glAttach(target, &att);
435 class ES3CheckerFactory : public CheckerFactory
438 Checker* createChecker (const glu::RenderContext& ctx) { return new ES3Checker(ctx); }
441 class TestGroup : public TestCaseGroup
444 TestGroup (Context& context);
447 ES3CheckerFactory m_checkerFactory;
448 fboc::Context m_fboc;
451 void TestGroup::init (void)
453 addChild(m_fboc.createRenderableTests());
454 addChild(m_fboc.createAttachmentTests());
455 addChild(m_fboc.createSizeTests());
457 TestCaseGroup* layerTests = new TestCaseGroup(
458 getContext(), "layer", "Tests for layer attachments");
460 static const NumLayersParams s_layersParams[] =
461 { // textureKind numLayers attachmentKind
462 { GL_TEXTURE_2D_ARRAY, 1, 0 },
463 { GL_TEXTURE_2D_ARRAY, 1, 3 },
464 { GL_TEXTURE_2D_ARRAY, 4, 3 },
465 { GL_TEXTURE_2D_ARRAY, 4, 15 },
466 { GL_TEXTURE_3D, 1, 0 },
467 { GL_TEXTURE_3D, 1, 15 },
468 { GL_TEXTURE_3D, 4, 15 },
469 { GL_TEXTURE_3D, 64, 15 },
472 for (const NumLayersParams* lp = DE_ARRAY_BEGIN(s_layersParams);
473 lp != DE_ARRAY_END(s_layersParams);
475 layerTests->addChild(new NumLayersTest(m_fboc, *lp));
477 addChild(layerTests);
479 TestCaseGroup* sampleTests = new TestCaseGroup(
480 getContext(), "samples", "Tests for multisample attachments");
482 static const NumSamplesParams s_samplesParams[] =
484 { { 0, SAMPLES_NONE, SAMPLES_NONE } },
485 { { 1, SAMPLES_NONE, SAMPLES_NONE } },
486 { { 2, SAMPLES_NONE, SAMPLES_NONE } },
487 { { 0, SAMPLES_TEXTURE, SAMPLES_NONE } },
488 { { 1, SAMPLES_TEXTURE, SAMPLES_NONE } },
489 { { 2, SAMPLES_TEXTURE, SAMPLES_NONE } },
490 { { 2, 1, SAMPLES_NONE } },
491 { { 2, 2, SAMPLES_NONE } },
492 { { 0, 0, SAMPLES_TEXTURE } },
499 for (const NumSamplesParams* lp = DE_ARRAY_BEGIN(s_samplesParams);
500 lp != DE_ARRAY_END(s_samplesParams);
502 sampleTests->addChild(new NumSamplesTest(m_fboc, *lp));
504 addChild(sampleTests);
507 TestGroup::TestGroup (Context& ctx)
508 : TestCaseGroup (ctx, "completeness", "Completeness tests")
509 , m_checkerFactory ()
510 , m_fboc (ctx.getTestContext(), ctx.getRenderContext(), m_checkerFactory)
512 const FormatEntries stdRange = GLS_ARRAY_RANGE(s_es3Formats);
513 const FormatExtEntries extRange = GLS_ARRAY_RANGE(s_es3ExtFormats);
515 m_fboc.addFormats(stdRange);
516 m_fboc.addExtFormats(extRange);
517 m_fboc.setHaveMulticolorAtts(true); // Vanilla ES3 has multiple color attachments
520 tcu::TestCaseGroup* createFboCompletenessTests (Context& context)
522 return new TestGroup(context);