5955250c526bb585aef9e45b2ec393297ae6818a
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fInternalFormatQueryTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Internal Format Query tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fInternalFormatQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es3fApiCase.hpp"
27 #include "gluRenderContext.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "deMath.h"
31
32 using namespace glw; // GLint and other GL types
33 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
34
35 namespace deqp
36 {
37 namespace gles3
38 {
39 namespace Functional
40 {
41 namespace
42 {
43
44 class SamplesCase : public ApiCase
45 {
46 public:
47         SamplesCase(Context& context, const char* name, const char* description, GLenum internalFormat, bool isIntegerInternalFormat)
48                 : ApiCase                                       (context, name, description)
49                 , m_internalFormat                      (internalFormat)
50                 , m_isIntegerInternalFormat     (isIntegerInternalFormat)
51         {
52         }
53
54         void test (void)
55         {
56                 using tcu::TestLog;
57
58                 StateQueryMemoryWriteGuard<GLint> sampleCounts;
59                 glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCounts);
60                 expectError(GL_NO_ERROR);
61
62                 if (!sampleCounts.verifyValidity(m_testCtx))
63                         return;
64
65                 m_testCtx.getLog() << TestLog::Message << "// sample counts is " << sampleCounts << TestLog::EndMessage;
66
67                 if (m_isIntegerInternalFormat && sampleCounts != 0)
68                 {
69                         // Since multisampling is not supported for signed and unsigned integer internal
70                         // formats, the value of NUM_SAMPLE_COUNTS will be zero for such formats.
71                         m_testCtx.getLog() << TestLog::Message << "// ERROR: integer internal formats should have NUM_SAMPLE_COUNTS = 0; got " << sampleCounts << TestLog::EndMessage;
72                         if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
73                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
74                 }
75
76                 if (sampleCounts == 0)
77                         return;
78
79                 std::vector<GLint> samples;
80                 samples.resize(sampleCounts, -1);
81                 glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_SAMPLES, sampleCounts, &samples[0]);
82                 expectError(GL_NO_ERROR);
83
84                 GLint prevSampleCount = 0;
85                 GLint sampleCount = 0;
86                 for (size_t ndx = 0; ndx < samples.size(); ++ndx, prevSampleCount = sampleCount)
87                 {
88                         sampleCount = samples[ndx];
89
90                         // sample count must be > 0
91                         if (sampleCount <= 0)
92                         {
93                                 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected sample count to be at least one; got " << sampleCount << TestLog::EndMessage;
94                                 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
95                                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
96                         }
97
98                         // samples must be ordered descending
99                         if (ndx != 0 && !(sampleCount < prevSampleCount))
100                         {
101                                 m_testCtx.getLog() << TestLog::Message
102                                         << "// ERROR: Expected sample count to be ordered in descending order;"
103                                         << "got " << prevSampleCount << " at index " << (ndx - 1) << ", and " << sampleCount << " at index " << ndx << TestLog::EndMessage;
104                                 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
105                                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid order");
106                         }
107                 }
108
109                 // the maximum value in SAMPLES is guaranteed to be at least the value of MAX_SAMPLES
110                 StateQueryMemoryWriteGuard<GLint> maxSamples;
111                 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
112                 expectError(GL_NO_ERROR);
113
114                 if (maxSamples.verifyValidity(m_testCtx))
115                 {
116                         const GLint maximumFormatSampleCount = samples[0];
117                         if (!(maximumFormatSampleCount >= maxSamples))
118                         {
119                                 m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected maximum value in SAMPLES (" << maximumFormatSampleCount << ") to be at least the value of MAX_SAMPLES (" << maxSamples << ")" << TestLog::EndMessage;
120                                 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
121                                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid maximum sample count");
122                         }
123                 }
124         }
125
126 private:
127         GLenum  m_internalFormat;
128         bool    m_isIntegerInternalFormat;
129 };
130
131 class SamplesBufferSizeCase : public ApiCase
132 {
133 public:
134         SamplesBufferSizeCase(Context& context, const char* name, const char* description, GLenum internalFormat)
135                 : ApiCase                       (context, name, description)
136                 , m_internalFormat      (internalFormat)
137         {
138         }
139
140         void test (void)
141         {
142                 using tcu::TestLog;
143
144                 StateQueryMemoryWriteGuard<GLint> sampleCounts;
145                 glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCounts);
146                 expectError(GL_NO_ERROR);
147
148                 if (!sampleCounts.verifyValidity(m_testCtx))
149                         return;
150
151                 // test with bufSize = 0
152                 GLint queryTargetValue = -1;
153                 glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 0, &queryTargetValue);
154                 expectError(GL_NO_ERROR);
155
156                 if (queryTargetValue != -1)
157                 {
158                         m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected output variable not to be written to." << TestLog::EndMessage;
159                         if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
160                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid write");
161                 }
162         }
163
164 private:
165         GLenum m_internalFormat;
166 };
167
168 } // anonymous
169
170
171 InternalFormatQueryTests::InternalFormatQueryTests (Context& context)
172         : TestCaseGroup(context, "internal_format", "Internal Format Query tests.")
173 {
174 }
175
176 void InternalFormatQueryTests::init (void)
177 {
178         const struct InternalFormat
179         {
180                 const char*     name;
181                 GLenum          format;
182                 bool            isIntegerFormat;
183         } internalFormats[] =
184         {
185                 // color renderable and unsized
186                 // \note These unsized formats seem to allowed by the spec, but they are not useful in any way. (You can't create a renderbuffer with such internalFormat)
187                 { "rgba",                                       GL_RGBA,                                false   },
188                 { "rgb",                                        GL_RGB,                                 false   },
189
190                 // color renderable
191                 { "r8",                                         GL_R8,                                  false   },
192                 { "rg8",                                        GL_RG8,                                 false   },
193                 { "rgb8",                                       GL_RGB8,                                false   },
194                 { "rgb565",                                     GL_RGB565,                              false   },
195                 { "rgba4",                                      GL_RGBA4,                               false   },
196                 { "rgb5_a1",                            GL_RGB5_A1,                             false   },
197                 { "rgba8",                                      GL_RGBA8,                               false   },
198                 { "rgb10_a2",                           GL_RGB10_A2,                    false   },
199                 { "rgb10_a2ui",                         GL_RGB10_A2UI,                  true    },
200                 { "srgb8_alpha8",                       GL_SRGB8_ALPHA8,                false   },
201                 { "r8i",                                        GL_R8I,                                 true    },
202                 { "r8ui",                                       GL_R8UI,                                true    },
203                 { "r16i",                                       GL_R16I,                                true    },
204                 { "r16ui",                                      GL_R16UI,                               true    },
205                 { "r32i",                                       GL_R32I,                                true    },
206                 { "r32ui",                                      GL_R32UI,                               true    },
207                 { "rg8i",                                       GL_RG8I,                                true    },
208                 { "rg8ui",                                      GL_RG8UI,                               true    },
209                 { "rg16i",                                      GL_RG16I,                               true    },
210                 { "rg16ui",                                     GL_RG16UI,                              true    },
211                 { "rg32i",                                      GL_RG32I,                               true    },
212                 { "rg32ui",                                     GL_RG32UI,                              true    },
213                 { "rgba8i",                                     GL_RGBA8I,                              true    },
214                 { "rgba8ui",                            GL_RGBA8UI,                             true    },
215                 { "rgba16i",                            GL_RGBA16I,                             true    },
216                 { "rgba16ui",                           GL_RGBA16UI,                    true    },
217                 { "rgba32i",                            GL_RGBA32I,                             true    },
218                 { "rgba32ui",                           GL_RGBA32UI,                    true    },
219
220                 // depth renderable
221                 { "depth_component16",          GL_DEPTH_COMPONENT16,   false   },
222                 { "depth_component24",          GL_DEPTH_COMPONENT24,   false   },
223                 { "depth_component32f",         GL_DEPTH_COMPONENT32F,  false   },
224                 { "depth24_stencil8",           GL_DEPTH24_STENCIL8,    false   },
225                 { "depth32f_stencil8",          GL_DEPTH32F_STENCIL8,   false   },
226
227                 // stencil renderable
228                 { "stencil_index8",                     GL_STENCIL_INDEX8,              false   }
229                 // DEPTH24_STENCIL8,  duplicate
230                 // DEPTH32F_STENCIL8  duplicate
231         };
232
233         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(internalFormats); ++ndx)
234         {
235                 const InternalFormat internalFormat = internalFormats[ndx];
236
237                 addChild(new SamplesCase(m_context, (std::string(internalFormat.name) + "_samples").c_str(), "SAMPLES and NUM_SAMPLE_COUNTS", internalFormat.format, internalFormat.isIntegerFormat));
238         }
239
240         addChild(new SamplesBufferSizeCase(m_context, "rgba8_samples_buffer", "SAMPLES bufSize parameter", GL_RGBA8));
241 }
242
243 } // Functional
244 } // gles3
245 } // deqp