Home | History | Annotate | Download | only in functional
      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 Rbo state query tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fRboStateQueryTests.hpp"
     25 #include "glsStateQueryUtil.hpp"
     26 #include "es3fApiCase.hpp"
     27 #include "gluRenderContext.hpp"
     28 #include "glwEnums.hpp"
     29 #include "glwFunctions.hpp"
     30 #include "deRandom.hpp"
     31 #include "deMath.h"
     32 
     33 using namespace glw; // GLint and other GL types
     34 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
     35 
     36 
     37 namespace deqp
     38 {
     39 namespace gles3
     40 {
     41 namespace Functional
     42 {
     43 namespace
     44 {
     45 
     46 void checkRenderbufferComponentSize (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, int r, int g, int b, int a, int d, int s)
     47 {
     48 	using tcu::TestLog;
     49 
     50 	const int referenceSizes[] = {r, g, b, a, d, s};
     51 	const GLenum paramNames[] =
     52 	{
     53 		GL_RENDERBUFFER_RED_SIZE,
     54 		GL_RENDERBUFFER_GREEN_SIZE,
     55 		GL_RENDERBUFFER_BLUE_SIZE,
     56 		GL_RENDERBUFFER_ALPHA_SIZE,
     57 		GL_RENDERBUFFER_DEPTH_SIZE,
     58 		GL_RENDERBUFFER_STENCIL_SIZE
     59 	};
     60 
     61 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(referenceSizes) == DE_LENGTH_OF_ARRAY(paramNames));
     62 
     63 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(referenceSizes); ++ndx)
     64 	{
     65 		if (referenceSizes[ndx] == -1)
     66 			continue;
     67 
     68 		StateQueryMemoryWriteGuard<GLint> state;
     69 		gl.glGetRenderbufferParameteriv(GL_RENDERBUFFER, paramNames[ndx], &state);
     70 
     71 		if (!state.verifyValidity(testCtx))
     72 			return;
     73 
     74 		if (state < referenceSizes[ndx])
     75 		{
     76 			testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to " << referenceSizes[ndx] << "; got " << state << TestLog::EndMessage;
     77 			if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
     78 				testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
     79 		}
     80 	}
     81 }
     82 
     83 void checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
     84 {
     85 	using tcu::TestLog;
     86 
     87 	if (got != expected)
     88 	{
     89 		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
     90 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
     91 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
     92 	}
     93 }
     94 
     95 void checkIntGreaterOrEqual (tcu::TestContext& testCtx, GLint got, GLint expected)
     96 {
     97 	using tcu::TestLog;
     98 
     99 	if (got < expected)
    100 	{
    101 		testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to " << expected << "; got " << got << TestLog::EndMessage;
    102 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    103 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
    104 	}
    105 }
    106 
    107 void checkRenderbufferParam (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLenum pname, GLenum reference)
    108 {
    109 	StateQueryMemoryWriteGuard<GLint> state;
    110 	gl.glGetRenderbufferParameteriv(GL_RENDERBUFFER, pname, &state);
    111 
    112 	if (state.verifyValidity(testCtx))
    113 		checkIntEquals(testCtx, state, reference);
    114 }
    115 
    116 void checkRenderbufferParamGreaterOrEqual (tcu::TestContext& testCtx, glu::CallLogWrapper& gl, GLenum pname, GLenum reference)
    117 {
    118 	StateQueryMemoryWriteGuard<GLint> state;
    119 	gl.glGetRenderbufferParameteriv(GL_RENDERBUFFER, pname, &state);
    120 
    121 	if (state.verifyValidity(testCtx))
    122 		checkIntGreaterOrEqual(testCtx, state, reference);
    123 }
    124 
    125 class RboSizeCase : public ApiCase
    126 {
    127 public:
    128 	RboSizeCase (Context& context, const char* name, const char* description)
    129 		: ApiCase(context, name, description)
    130 	{
    131 	}
    132 
    133 	void test (void)
    134 	{
    135 		de::Random rnd(0xabcdef);
    136 
    137 		GLuint renderbufferID = 0;
    138 		glGenRenderbuffers(1, &renderbufferID);
    139 		glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
    140 		expectError(GL_NO_ERROR);
    141 
    142 		checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_WIDTH,		0);
    143 		checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_HEIGHT,	0);
    144 		expectError(GL_NO_ERROR);
    145 
    146 		const int numIterations = 60;
    147 		for (int i = 0; i < numIterations; ++i)
    148 		{
    149 			const GLint w = rnd.getInt(0, 128);
    150 			const GLint h = rnd.getInt(0, 128);
    151 
    152 			glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, w, h);
    153 
    154 			checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_WIDTH,		w);
    155 			checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_HEIGHT,	h);
    156 		}
    157 
    158 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
    159 		glDeleteRenderbuffers(1, &renderbufferID);
    160 	}
    161 };
    162 
    163 class RboInternalFormatCase : public ApiCase
    164 {
    165 public:
    166 	RboInternalFormatCase (Context& context, const char* name, const char* description)
    167 		: ApiCase(context, name, description)
    168 	{
    169 	}
    170 
    171 	void test (void)
    172 	{
    173 		GLuint renderbufferID = 0;
    174 		glGenRenderbuffers(1, &renderbufferID);
    175 		glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
    176 		expectError(GL_NO_ERROR);
    177 
    178 		checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, GL_RGBA4);
    179 		expectError(GL_NO_ERROR);
    180 
    181 		const GLenum requiredColorformats[] =
    182 		{
    183 			GL_R8, GL_RG8, GL_RGB8, GL_RGB565, GL_RGBA4, GL_RGB5_A1, GL_RGBA8, GL_RGB10_A2,
    184 			GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_R8I, GL_R8UI, GL_R16I, GL_R16UI, GL_R32I, GL_R32UI,
    185 			GL_RG8I, GL_RG8UI, GL_RG16I, GL_RG16UI, GL_RG32I, GL_RG32UI, GL_RGBA8I, GL_RGBA8UI,
    186 			GL_RGBA16I, GL_RGBA16UI, GL_RGBA32I, GL_RGBA32UI
    187 		};
    188 
    189 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorformats); ++ndx)
    190 		{
    191 			glRenderbufferStorage(GL_RENDERBUFFER, requiredColorformats[ndx], 128, 128);
    192 			expectError(GL_NO_ERROR);
    193 
    194 			checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_INTERNAL_FORMAT, requiredColorformats[ndx]);
    195 		}
    196 
    197 		glDeleteRenderbuffers(1, &renderbufferID);
    198 	}
    199 };
    200 
    201 class RboComponentSizeColorCase : public ApiCase
    202 {
    203 public:
    204 	RboComponentSizeColorCase (Context& context, const char* name, const char* description)
    205 		: ApiCase(context, name, description)
    206 	{
    207 	}
    208 
    209 	void test (void)
    210 	{
    211 		GLuint renderbufferID = 0;
    212 		glGenRenderbuffers(1, &renderbufferID);
    213 		glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
    214 		expectError(GL_NO_ERROR);
    215 
    216 		checkRenderbufferComponentSize(m_testCtx, *this, 0, 0, 0, 0, 0, 0);
    217 		expectError(GL_NO_ERROR);
    218 
    219 		const struct ColorFormat
    220 		{
    221 			GLenum	internalFormat;
    222 			int		bitsR, bitsG, bitsB, bitsA;
    223 		} requiredColorFormats[] =
    224 		{
    225 			{ GL_R8,			8,	0,	0,	0	},
    226 			{ GL_RG8,			8,	8,	0,	0	},
    227 			{ GL_RGB8,			8,	8,	8,	0	},
    228 			{ GL_RGB565,		5,	6,	5,	0	},
    229 			{ GL_RGBA4,			4,	4,	4,	4	},
    230 			{ GL_RGB5_A1, 		5,	5,	5,	1	},
    231 			{ GL_RGBA8,			8,	8,	8,	8	},
    232 			{ GL_RGB10_A2,		10, 10, 10, 2	},
    233 			{ GL_RGB10_A2UI,	10, 10, 10, 2	},
    234 			{ GL_SRGB8_ALPHA8,	8,	8,	8,	8	},
    235 			{ GL_R8I,			8,	0,	0,	0	},
    236 			{ GL_R8UI,			8,	0,	0,	0	},
    237 			{ GL_R16I,			16, 0,	0,	0	},
    238 			{ GL_R16UI,			16, 0,	0,	0	},
    239 			{ GL_R32I,			32, 0,	0,	0	},
    240 			{ GL_R32UI,			32, 0,	0,	0	},
    241 			{ GL_RG8I,			8,	8,	0,	0	},
    242 			{ GL_RG8UI,			8,	8,	0,	0	},
    243 			{ GL_RG16I,			16, 16, 0,	0	},
    244 			{ GL_RG16UI,		16, 16, 0,	0	},
    245 			{ GL_RG32I,			32, 32, 0,	0	},
    246 			{ GL_RG32UI,		32, 32, 0,	0	},
    247 			{ GL_RGBA8I,		8,	8,	8,	8	},
    248 			{ GL_RGBA8UI,		8,	8,	8,	8	},
    249 			{ GL_RGBA16I,		16, 16, 16, 16	},
    250 			{ GL_RGBA16UI,		16, 16, 16, 16	},
    251 			{ GL_RGBA32I,		32, 32, 32, 32	},
    252 			{ GL_RGBA32UI,		32, 32, 32, 32	}
    253 		};
    254 
    255 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredColorFormats); ++ndx)
    256 		{
    257 			glRenderbufferStorage(GL_RENDERBUFFER, requiredColorFormats[ndx].internalFormat, 128, 128);
    258 			expectError(GL_NO_ERROR);
    259 
    260 			checkRenderbufferComponentSize(m_testCtx, *this, requiredColorFormats[ndx].bitsR, requiredColorFormats[ndx].bitsG, requiredColorFormats[ndx].bitsB, requiredColorFormats[ndx].bitsA, -1, -1);
    261 		}
    262 
    263 		glDeleteRenderbuffers(1, &renderbufferID);
    264 	}
    265 };
    266 
    267 class RboComponentSizeDepthCase : public ApiCase
    268 {
    269 public:
    270 	RboComponentSizeDepthCase (Context& context, const char* name, const char* description)
    271 		: ApiCase(context, name, description)
    272 	{
    273 	}
    274 
    275 	void test (void)
    276 	{
    277 		using tcu::TestLog;
    278 
    279 		GLuint renderbufferID = 0;
    280 		glGenRenderbuffers(1, &renderbufferID);
    281 		glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
    282 		expectError(GL_NO_ERROR);
    283 
    284 		const struct DepthFormat
    285 		{
    286 			GLenum	internalFormat;
    287 			int		dbits;
    288 			int		sbits;
    289 		} requiredDepthFormats[] =
    290 		{
    291 			{ GL_DEPTH_COMPONENT16,		16, 0 },
    292 			{ GL_DEPTH_COMPONENT24,		24, 0 },
    293 			{ GL_DEPTH_COMPONENT32F,	32, 0 },
    294 			{ GL_DEPTH24_STENCIL8,		24, 8 },
    295 			{ GL_DEPTH32F_STENCIL8,		32, 8 },
    296 		};
    297 
    298 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requiredDepthFormats); ++ndx)
    299 		{
    300 			glRenderbufferStorage(GL_RENDERBUFFER, requiredDepthFormats[ndx].internalFormat, 128, 128);
    301 			expectError(GL_NO_ERROR);
    302 
    303 			checkRenderbufferComponentSize(m_testCtx, *this, -1, -1, -1, -1, requiredDepthFormats[ndx].dbits, requiredDepthFormats[ndx].sbits);
    304 		}
    305 
    306 		// STENCIL_INDEX8 is required, in that case sBits >= 8
    307 		{
    308 			glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 128, 128);
    309 			expectError(GL_NO_ERROR);
    310 
    311 			StateQueryMemoryWriteGuard<GLint> state;
    312 			glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STENCIL_SIZE, &state);
    313 
    314 			if (state.verifyValidity(m_testCtx) && state < 8)
    315 			{
    316 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected greater or equal to 8; got " << state << TestLog::EndMessage;
    317 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    318 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
    319 			}
    320 		}
    321 
    322 		glDeleteRenderbuffers(1, &renderbufferID);
    323 	}
    324 };
    325 
    326 class RboSamplesCase : public ApiCase
    327 {
    328 public:
    329 	RboSamplesCase (Context& context, const char* name, const char* description)
    330 		: ApiCase(context, name, description)
    331 	{
    332 	}
    333 
    334 	void test (void)
    335 	{
    336 		de::Random rnd(0xabcdef);
    337 
    338 		GLuint renderbufferID = 0;
    339 		glGenRenderbuffers(1, &renderbufferID);
    340 		glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID);
    341 		expectError(GL_NO_ERROR);
    342 
    343 		checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, 0);
    344 		expectError(GL_NO_ERROR);
    345 
    346 		StateQueryMemoryWriteGuard<GLint> max_samples;
    347 		glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
    348 		if (!max_samples.verifyValidity(m_testCtx))
    349 			return;
    350 
    351 		// 0 samples is a special case
    352 		{
    353 			glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, 128, 128);
    354 			expectError(GL_NO_ERROR);
    355 
    356 			checkRenderbufferParam(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, 0);
    357 		}
    358 
    359 		// test [1, n] samples
    360 		for (int samples = 1; samples <= max_samples; ++samples)
    361 		{
    362 			glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, 128, 128);
    363 			expectError(GL_NO_ERROR);
    364 
    365 			checkRenderbufferParamGreaterOrEqual(m_testCtx, *this, GL_RENDERBUFFER_SAMPLES, samples);
    366 		}
    367 
    368 		glDeleteRenderbuffers(1, &renderbufferID);
    369 	}
    370 };
    371 
    372 } // anonymous
    373 
    374 
    375 RboStateQueryTests::RboStateQueryTests (Context& context)
    376 	: TestCaseGroup(context, "rbo", "Rbo State Query tests")
    377 {
    378 }
    379 
    380 void RboStateQueryTests::init (void)
    381 {
    382 	addChild(new RboSizeCase				(m_context, "renderbuffer_size",					"RENDERBUFFER_WIDTH and RENDERBUFFER_HEIGHT"));
    383 	addChild(new RboInternalFormatCase		(m_context, "renderbuffer_internal_format",			"RENDERBUFFER_INTERNAL_FORMAT"));
    384 	addChild(new RboComponentSizeColorCase	(m_context, "renderbuffer_component_size_color",	"RENDERBUFFER_x_SIZE"));
    385 	addChild(new RboComponentSizeDepthCase	(m_context, "renderbuffer_component_size_depth",	"RENDERBUFFER_x_SIZE"));
    386 	addChild(new RboSamplesCase				(m_context, "renderbuffer_samples",					"RENDERBUFFER_SAMPLES"));
    387 }
    388 
    389 } // Functional
    390 } // gles3
    391 } // deqp
    392