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:
SamplesCase(Context & context,const char * name,const char * description,GLenum internalFormat,bool isIntegerInternalFormat)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
test(void)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:
SamplesBufferSizeCase(Context & context,const char * name,const char * description,GLenum internalFormat)134 SamplesBufferSizeCase(Context& context, const char* name, const char* description, GLenum internalFormat)
135 : ApiCase (context, name, description)
136 , m_internalFormat (internalFormat)
137 {
138 }
139
test(void)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
InternalFormatQueryTests(Context & context)171 InternalFormatQueryTests::InternalFormatQueryTests (Context& context)
172 : TestCaseGroup(context, "internal_format", "Internal Format Query tests.")
173 {
174 }
175
init(void)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
246