Fix PIPELINE_STAGE_TOP_OF_PIPE_BIT usage in api tests
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fInternalFormatQueryTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 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 Internal format query tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "es31fInternalFormatQueryTests.hpp"
25 #include "tcuTestLog.hpp"
26 #include "gluRenderContext.hpp"
27 #include "gluStrUtil.hpp"
28 #include "gluContextInfo.hpp"
29 #include "glwFunctions.hpp"
30 #include "glwEnums.hpp"
31
32 namespace deqp
33 {
34 namespace gles31
35 {
36 namespace Functional
37 {
38 namespace
39 {
40
41 class FormatSamplesCase : public TestCase
42 {
43 public:
44         enum FormatType
45         {
46                 FORMAT_COLOR,
47                 FORMAT_INT,
48                 FORMAT_DEPTH_STENCIL
49         };
50
51                                                 FormatSamplesCase       (Context& ctx, const char* name, const char* desc, glw::GLenum texTarget, glw::GLenum internalFormat, FormatType type);
52 private:
53         void                            init                            (void);
54         IterateResult           iterate                         (void);
55
56         const glw::GLenum       m_target;
57         const glw::GLenum       m_internalFormat;
58         const FormatType        m_type;
59 };
60
61 FormatSamplesCase::FormatSamplesCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, glw::GLenum internalFormat, FormatType type)
62         : TestCase                      (ctx, name, desc)
63         , m_target                      (target)
64         , m_internalFormat      (internalFormat)
65         , m_type                        (type)
66 {
67         DE_ASSERT(m_target == GL_TEXTURE_2D_MULTISAMPLE                 ||
68                           m_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY   ||
69                           m_target == GL_RENDERBUFFER);
70 }
71
72 void FormatSamplesCase::init (void)
73 {
74         const bool isTextureTarget      =       (m_target == GL_TEXTURE_2D_MULTISAMPLE) ||
75                                                                         (m_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
76         const bool supportsES32         =       contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
77
78         if (!supportsES32 && m_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY && !m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
79                 TCU_THROW(NotSupportedError, "Test requires OES_texture_storage_multisample_2d_array extension or a context version equal or higher than 3.2");
80
81         // stencil8 textures are not supported without GL_OES_texture_stencil8 extension
82         if (!supportsES32 && isTextureTarget && m_internalFormat == GL_STENCIL_INDEX8 && !m_context.getContextInfo().isExtensionSupported("GL_OES_texture_stencil8"))
83                 TCU_THROW(NotSupportedError, "Test requires GL_OES_texture_stencil8 extension or a context version equal or higher than 3.2");
84 }
85
86 FormatSamplesCase::IterateResult FormatSamplesCase::iterate (void)
87 {
88         const glw::Functions&   gl                              = m_context.getRenderContext().getFunctions();
89         bool                                    isFloatFormat   = false;
90         bool                                    error                   = false;
91         glw::GLint                              maxSamples              = 0;
92         glw::GLint                              numSampleCounts = 0;
93         const bool                              supportsES32                    = contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
94
95         if (!supportsES32)
96         {
97                 if (m_internalFormat == GL_RGBA16F || m_internalFormat == GL_R32F || m_internalFormat == GL_RG32F || m_internalFormat == GL_RGBA32F || m_internalFormat == GL_R16F || m_internalFormat == GL_RG16F || m_internalFormat == GL_R11F_G11F_B10F)
98                 {
99                         TCU_THROW(NotSupportedError, "The internal format is not supported in a context lower than 3.2");
100                 }
101         }
102         else if (m_internalFormat == GL_RGBA16F || m_internalFormat == GL_R32F || m_internalFormat == GL_RG32F || m_internalFormat == GL_RGBA32F)
103         {
104                 isFloatFormat = true;
105         }
106
107         // Lowest limit
108         {
109                 const glw::GLenum samplesEnum = (m_type == FORMAT_COLOR) ? (GL_MAX_COLOR_TEXTURE_SAMPLES) : (m_type == FORMAT_INT) ? (GL_MAX_INTEGER_SAMPLES) : (GL_MAX_DEPTH_TEXTURE_SAMPLES);
110                 m_testCtx.getLog() << tcu::TestLog::Message << "Format must support sample count of " << glu::getGettableStateStr(samplesEnum) << tcu::TestLog::EndMessage;
111
112                 gl.getIntegerv(samplesEnum, &maxSamples);
113                 GLU_EXPECT_NO_ERROR(gl.getError(), "get MAX_*_SAMPLES");
114
115                 m_testCtx.getLog() << tcu::TestLog::Message << glu::getGettableStateStr(samplesEnum) << " = " << maxSamples << tcu::TestLog::EndMessage;
116
117                 if (maxSamples < 1)
118                 {
119                         m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: minimum value of "  << glu::getGettableStateStr(samplesEnum) << " is 1" << tcu::TestLog::EndMessage;
120                         error = true;
121                 }
122         }
123
124         // Number of sample counts
125         {
126                 gl.getInternalformativ(m_target, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
127                 GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_NUM_SAMPLE_COUNTS");
128
129                 m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << tcu::TestLog::EndMessage;
130
131                 if (!isFloatFormat)
132                 {
133                         if (numSampleCounts < 1)
134                         {
135                                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Format MUST support some multisample configuration, got GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << tcu::TestLog::EndMessage;
136                                 error = true;
137                         }
138                 }
139         }
140
141         // Sample counts
142         {
143                 tcu::MessageBuilder             samplesMsg      (&m_testCtx.getLog());
144                 std::vector<glw::GLint> samples         (numSampleCounts > 0 ? numSampleCounts : 1);
145
146                 if (numSampleCounts > 0 || isFloatFormat)
147                 {
148                         gl.getInternalformativ(m_target, m_internalFormat, GL_SAMPLES, numSampleCounts, &samples[0]);
149                         GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_SAMPLES");
150                 }
151                 else
152                         TCU_FAIL("glGetInternalFormativ() reported 0 supported sample counts");
153
154                 // make a pretty log
155
156                 samplesMsg << "GL_SAMPLES = [";
157                 for (size_t ndx = 0; ndx < samples.size(); ++ndx)
158                 {
159                         if (ndx)
160                                 samplesMsg << ", ";
161                         samplesMsg << samples[ndx];
162                 }
163                 samplesMsg << "]" << tcu::TestLog::EndMessage;
164
165                 // Samples are in order
166                 for (size_t ndx = 1; ndx < samples.size(); ++ndx)
167                 {
168                         if (samples[ndx-1] <= samples[ndx])
169                         {
170                                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Samples must be ordered descending." << tcu::TestLog::EndMessage;
171                                 error = true;
172                                 break;
173                         }
174                 }
175
176                 // samples are positive
177                 for (size_t ndx = 1; ndx < samples.size(); ++ndx)
178                 {
179                         if (samples[ndx-1] <= 0)
180                         {
181                                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Only positive SAMPLES allowed." << tcu::TestLog::EndMessage;
182                                 error = true;
183                                 break;
184                         }
185                 }
186
187                 // maxSamples must be supported
188                 if (!isFloatFormat)
189                 {
190                         if (samples[0] < maxSamples)
191                         {
192                                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: MAX_*_SAMPLES must be supported." << tcu::TestLog::EndMessage;
193                                 error = true;
194                         }
195                 }
196         }
197
198         // Result
199         if (!error)
200                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
201         else
202                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
203
204         return STOP;
205 }
206
207 class NumSampleCountsBufferCase : public TestCase
208 {
209 public:
210                                         NumSampleCountsBufferCase       (Context& ctx, const char* name, const char* desc);
211
212 private:
213         IterateResult   iterate                                         (void);
214 };
215
216 NumSampleCountsBufferCase::NumSampleCountsBufferCase (Context& ctx, const char* name, const char* desc)
217         : TestCase(ctx, name, desc)
218 {
219 }
220
221 NumSampleCountsBufferCase::IterateResult NumSampleCountsBufferCase::iterate (void)
222 {
223         const glw::GLint                defaultValue    = -123; // queries always return positive values
224         const glw::Functions&   gl                              = m_context.getRenderContext().getFunctions();
225         bool                                    error                   = false;
226
227         // Query to larger buffer
228         {
229                 glw::GLint buffer[2] = { defaultValue, defaultValue };
230
231                 m_testCtx.getLog() << tcu::TestLog::Message << "Querying GL_NUM_SAMPLE_COUNTS to larger-than-needed buffer." << tcu::TestLog::EndMessage;
232                 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 2, buffer);
233                 GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_NUM_SAMPLE_COUNTS");
234
235                 if (buffer[1] != defaultValue)
236                 {
237                         m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: trailing values were modified." << tcu::TestLog::EndMessage;
238                         error = true;
239                 }
240         }
241
242         // Query to empty buffer
243         {
244                 glw::GLint buffer[1] = { defaultValue };
245
246                 m_testCtx.getLog() << tcu::TestLog::Message << "Querying GL_NUM_SAMPLE_COUNTS to zero-sized buffer." << tcu::TestLog::EndMessage;
247                 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 0, buffer);
248                 GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_NUM_SAMPLE_COUNTS");
249
250                 if (buffer[0] != defaultValue)
251                 {
252                         m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Query wrote over buffer bounds." << tcu::TestLog::EndMessage;
253                         error = true;
254                 }
255         }
256
257         // Result
258         if (!error)
259                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
260         else
261                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected buffer modification");
262
263         return STOP;
264 }
265
266 class SamplesBufferCase : public TestCase
267 {
268 public:
269                                         SamplesBufferCase       (Context& ctx, const char* name, const char* desc);
270
271 private:
272         IterateResult   iterate                         (void);
273 };
274
275 SamplesBufferCase::SamplesBufferCase (Context& ctx, const char* name, const char* desc)
276         : TestCase(ctx, name, desc)
277 {
278 }
279
280 SamplesBufferCase::IterateResult SamplesBufferCase::iterate (void)
281 {
282         const glw::GLint                defaultValue    = -123; // queries always return positive values
283         const glw::Functions&   gl                              = m_context.getRenderContext().getFunctions();
284         bool                                    error                   = false;
285
286         glw::GLint                              numSampleCounts = 0;
287
288         // Number of sample counts
289         {
290                 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
291                 GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_NUM_SAMPLE_COUNTS");
292
293                 m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << tcu::TestLog::EndMessage;
294         }
295
296         if (numSampleCounts < 1)
297         {
298                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Format MUST support some multisample configuration, got GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << tcu::TestLog::EndMessage;
299                 error = true;
300         }
301         else
302         {
303                 // Query to larger buffer
304                 {
305                         std::vector<glw::GLint> buffer(numSampleCounts + 1, defaultValue);
306
307                         m_testCtx.getLog() << tcu::TestLog::Message << "Querying GL_SAMPLES to larger-than-needed buffer." << tcu::TestLog::EndMessage;
308                         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, (glw::GLsizei)buffer.size(), &buffer[0]);
309                         GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_SAMPLES");
310
311                         if (buffer.back() != defaultValue)
312                         {
313                                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: trailing value was modified." << tcu::TestLog::EndMessage;
314                                 error = true;
315                         }
316                 }
317
318                 // Query to smaller buffer
319                 if (numSampleCounts > 2)
320                 {
321                         glw::GLint buffer[3] = { defaultValue, defaultValue, defaultValue };
322
323                         m_testCtx.getLog() << tcu::TestLog::Message << "Querying GL_SAMPLES to buffer with bufSize=2." << tcu::TestLog::EndMessage;
324                         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, 2, buffer);
325                         GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_SAMPLES");
326
327                         if (buffer[2] != defaultValue)
328                         {
329                                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Query wrote over buffer bounds." << tcu::TestLog::EndMessage;
330                                 error = true;
331                         }
332                 }
333
334                 // Query to empty buffer
335                 {
336                         glw::GLint buffer[1] = { defaultValue };
337
338                         m_testCtx.getLog() << tcu::TestLog::Message << "Querying GL_SAMPLES to zero-sized buffer." << tcu::TestLog::EndMessage;
339                         gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, 0, buffer);
340                         GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_SAMPLES");
341
342                         if (buffer[0] != defaultValue)
343                         {
344                                 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Query wrote over buffer bounds." << tcu::TestLog::EndMessage;
345                                 error = true;
346                         }
347                 }
348         }
349
350         // Result
351         if (!error)
352                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
353         else
354                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected buffer modification");
355
356         return STOP;
357 }
358
359 } // anonymous
360
361 InternalFormatQueryTests::InternalFormatQueryTests (Context& context)
362         : TestCaseGroup(context, "internal_format", "Internal format queries")
363 {
364 }
365
366 InternalFormatQueryTests::~InternalFormatQueryTests (void)
367 {
368 }
369
370 void InternalFormatQueryTests::init (void)
371 {
372         static const struct InternalFormat
373         {
374                 const char*                                             name;
375                 glw::GLenum                                             format;
376                 FormatSamplesCase::FormatType   type;
377         } internalFormats[] =
378         {
379                 // color renderable
380                 { "r8",                                         GL_R8,                                  FormatSamplesCase::FORMAT_COLOR                 },
381                 { "rg8",                                        GL_RG8,                                 FormatSamplesCase::FORMAT_COLOR                 },
382                 { "rgb8",                                       GL_RGB8,                                FormatSamplesCase::FORMAT_COLOR                 },
383                 { "rgb565",                                     GL_RGB565,                              FormatSamplesCase::FORMAT_COLOR                 },
384                 { "rgba4",                                      GL_RGBA4,                               FormatSamplesCase::FORMAT_COLOR                 },
385                 { "rgb5_a1",                            GL_RGB5_A1,                             FormatSamplesCase::FORMAT_COLOR                 },
386                 { "rgba8",                                      GL_RGBA8,                               FormatSamplesCase::FORMAT_COLOR                 },
387                 { "rgb10_a2",                           GL_RGB10_A2,                    FormatSamplesCase::FORMAT_COLOR                 },
388                 { "rgb10_a2ui",                         GL_RGB10_A2UI,                  FormatSamplesCase::FORMAT_INT                   },
389                 { "srgb8_alpha8",                       GL_SRGB8_ALPHA8,                FormatSamplesCase::FORMAT_COLOR                 },
390                 { "r8i",                                        GL_R8I,                                 FormatSamplesCase::FORMAT_INT                   },
391                 { "r8ui",                                       GL_R8UI,                                FormatSamplesCase::FORMAT_INT                   },
392                 { "r16i",                                       GL_R16I,                                FormatSamplesCase::FORMAT_INT                   },
393                 { "r16ui",                                      GL_R16UI,                               FormatSamplesCase::FORMAT_INT                   },
394                 { "r32i",                                       GL_R32I,                                FormatSamplesCase::FORMAT_INT                   },
395                 { "r32ui",                                      GL_R32UI,                               FormatSamplesCase::FORMAT_INT                   },
396                 { "rg8i",                                       GL_RG8I,                                FormatSamplesCase::FORMAT_INT                   },
397                 { "rg8ui",                                      GL_RG8UI,                               FormatSamplesCase::FORMAT_INT                   },
398                 { "rg16i",                                      GL_RG16I,                               FormatSamplesCase::FORMAT_INT                   },
399                 { "rg16ui",                                     GL_RG16UI,                              FormatSamplesCase::FORMAT_INT                   },
400                 { "rg32i",                                      GL_RG32I,                               FormatSamplesCase::FORMAT_INT                   },
401                 { "rg32ui",                                     GL_RG32UI,                              FormatSamplesCase::FORMAT_INT                   },
402                 { "rgba8i",                                     GL_RGBA8I,                              FormatSamplesCase::FORMAT_INT                   },
403                 { "rgba8ui",                            GL_RGBA8UI,                             FormatSamplesCase::FORMAT_INT                   },
404                 { "rgba16i",                            GL_RGBA16I,                             FormatSamplesCase::FORMAT_INT                   },
405                 { "rgba16ui",                           GL_RGBA16UI,                    FormatSamplesCase::FORMAT_INT                   },
406                 { "rgba32i",                            GL_RGBA32I,                             FormatSamplesCase::FORMAT_INT                   },
407                 { "rgba32ui",                           GL_RGBA32UI,                    FormatSamplesCase::FORMAT_INT                   },
408
409                 // float formats
410                 { "r16f",                                       GL_R16F,                                FormatSamplesCase::FORMAT_COLOR                 },
411                 { "rg16f",                                      GL_RG16F,                               FormatSamplesCase::FORMAT_COLOR                 },
412                 { "rgba16f",                            GL_RGBA16F,                             FormatSamplesCase::FORMAT_COLOR                 },
413                 { "r32f",                                       GL_R32F,                                FormatSamplesCase::FORMAT_INT                   },
414                 { "rg32f",                                      GL_RG32F,                               FormatSamplesCase::FORMAT_INT                   },
415                 { "rgba32f",                            GL_RGBA32F,                             FormatSamplesCase::FORMAT_INT                   },
416                 { "r11f_g11f_b10f",                     GL_R11F_G11F_B10F,              FormatSamplesCase::FORMAT_COLOR                 },
417
418                 // depth renderable
419                 { "depth_component16",          GL_DEPTH_COMPONENT16,   FormatSamplesCase::FORMAT_DEPTH_STENCIL },
420                 { "depth_component24",          GL_DEPTH_COMPONENT24,   FormatSamplesCase::FORMAT_DEPTH_STENCIL },
421                 { "depth_component32f",         GL_DEPTH_COMPONENT32F,  FormatSamplesCase::FORMAT_DEPTH_STENCIL },
422                 { "depth24_stencil8",           GL_DEPTH24_STENCIL8,    FormatSamplesCase::FORMAT_DEPTH_STENCIL },
423                 { "depth32f_stencil8",          GL_DEPTH32F_STENCIL8,   FormatSamplesCase::FORMAT_DEPTH_STENCIL },
424
425                 // stencil renderable
426                 { "stencil_index8",                     GL_STENCIL_INDEX8,              FormatSamplesCase::FORMAT_DEPTH_STENCIL }
427                 // DEPTH24_STENCIL8,  duplicate
428                 // DEPTH32F_STENCIL8  duplicate
429         };
430
431         static const struct
432         {
433                 const char*     name;
434                 deUint32        target;
435         } textureTargets[] =
436         {
437                 { "renderbuffer",                                       GL_RENDERBUFFER                                 },
438                 { "texture_2d_multisample",                     GL_TEXTURE_2D_MULTISAMPLE               },
439                 { "texture_2d_multisample_array",       GL_TEXTURE_2D_MULTISAMPLE_ARRAY },
440         };
441
442         for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(textureTargets); ++groupNdx)
443         {
444                 tcu::TestCaseGroup* const       group           = new tcu::TestCaseGroup(m_testCtx, textureTargets[groupNdx].name, glu::getInternalFormatTargetName(textureTargets[groupNdx].target));
445                 const glw::GLenum                       texTarget       = textureTargets[groupNdx].target;
446
447                 addChild(group);
448
449                 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(internalFormats); ++caseNdx)
450                 {
451                         const std::string name = std::string(internalFormats[caseNdx].name) + "_samples";
452                         const std::string desc = std::string("Verify GL_SAMPLES of ") + internalFormats[caseNdx].name;
453
454                         group->addChild(new FormatSamplesCase(m_context, name.c_str(), desc.c_str(), texTarget, internalFormats[caseNdx].format, internalFormats[caseNdx].type));
455                 }
456         }
457
458         // Check buffer sizes are honored
459         {
460                 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "partial_query", "Query data to too short a buffer");
461
462                 addChild(group);
463
464                 group->addChild(new NumSampleCountsBufferCase   (m_context, "num_sample_counts",        "Query GL_NUM_SAMPLE_COUNTS to too short a buffer"));
465                 group->addChild(new SamplesBufferCase                   (m_context, "samples",                          "Query GL_SAMPLES to too short a buffer"));
466         }
467 }
468
469 } // Functional
470 } // gles31
471 } // deqp