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 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 (sampleCounts == 0)
     68 			return;
     69 
     70 		std::vector<GLint> samples;
     71 		samples.resize(sampleCounts, -1);
     72 		glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_SAMPLES, sampleCounts, &samples[0]);
     73 		expectError(GL_NO_ERROR);
     74 
     75 		GLint prevSampleCount = 0;
     76 		GLint sampleCount = 0;
     77 		for (size_t ndx = 0; ndx < samples.size(); ++ndx, prevSampleCount = sampleCount)
     78 		{
     79 			sampleCount = samples[ndx];
     80 
     81 			// sample count must be > 0
     82 			if (sampleCount <= 0)
     83 			{
     84 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected sample count to be at least one; got " << sampleCount << TestLog::EndMessage;
     85 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
     86 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
     87 			}
     88 
     89 			// samples must be ordered descending
     90 			if (ndx != 0 && !(sampleCount < prevSampleCount))
     91 			{
     92 				m_testCtx.getLog() << TestLog::Message
     93 					<< "// ERROR: Expected sample count to be ordered in descending order;"
     94 					<< "got " << prevSampleCount << " at index " << (ndx - 1) << ", and " << sampleCount << " at index " << ndx << TestLog::EndMessage;
     95 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
     96 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid order");
     97 			}
     98 		}
     99 
    100 		if (!m_isIntegerInternalFormat)
    101 		{
    102 			// the maximum value in SAMPLES is guaranteed to be at least the value of MAX_SAMPLES
    103 			StateQueryMemoryWriteGuard<GLint> maxSamples;
    104 			glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
    105 			expectError(GL_NO_ERROR);
    106 
    107 			if (maxSamples.verifyValidity(m_testCtx))
    108 			{
    109 				const GLint maximumFormatSampleCount = samples[0];
    110 				if (!(maximumFormatSampleCount >= maxSamples))
    111 				{
    112 					m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected maximum value in SAMPLES (" << maximumFormatSampleCount << ") to be at least the value of MAX_SAMPLES (" << maxSamples << ")" << TestLog::EndMessage;
    113 					if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    114 						m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid maximum sample count");
    115 				}
    116 		  }
    117 		}
    118 	}
    119 
    120 private:
    121 	const GLenum	m_internalFormat;
    122 	const bool		m_isIntegerInternalFormat;
    123 };
    124 
    125 class SamplesBufferSizeCase : public ApiCase
    126 {
    127 public:
    128 	SamplesBufferSizeCase(Context& context, const char* name, const char* description, GLenum internalFormat)
    129 		: ApiCase			(context, name, description)
    130 		, m_internalFormat	(internalFormat)
    131 	{
    132 	}
    133 
    134 	void test (void)
    135 	{
    136 		using tcu::TestLog;
    137 
    138 		StateQueryMemoryWriteGuard<GLint> sampleCounts;
    139 		glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCounts);
    140 		expectError(GL_NO_ERROR);
    141 
    142 		if (!sampleCounts.verifyValidity(m_testCtx))
    143 			return;
    144 
    145 		// test with bufSize = 0
    146 		GLint queryTargetValue = -1;
    147 		glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 0, &queryTargetValue);
    148 		expectError(GL_NO_ERROR);
    149 
    150 		if (queryTargetValue != -1)
    151 		{
    152 			m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected output variable not to be written to." << TestLog::EndMessage;
    153 			if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    154 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid write");
    155 		}
    156 	}
    157 
    158 private:
    159 	GLenum m_internalFormat;
    160 };
    161 
    162 } // anonymous
    163 
    164 
    165 InternalFormatQueryTests::InternalFormatQueryTests (Context& context)
    166 	: TestCaseGroup(context, "internal_format", "Internal Format Query tests.")
    167 {
    168 }
    169 
    170 void InternalFormatQueryTests::init (void)
    171 {
    172 	const struct InternalFormat
    173 	{
    174 		const char*	name;
    175 		GLenum		format;
    176 		bool		isIntegerFormat;
    177 	} internalFormats[] =
    178 	{
    179 		// color renderable and unsized
    180 		// \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)
    181 		{ "rgba",					GL_RGBA,				false	},
    182 		{ "rgb",					GL_RGB,					false	},
    183 
    184 		// color renderable
    185 		{ "r8",						GL_R8,					false	},
    186 		{ "rg8",					GL_RG8,					false	},
    187 		{ "rgb8",					GL_RGB8,				false	},
    188 		{ "rgb565",					GL_RGB565,				false	},
    189 		{ "rgba4",					GL_RGBA4,				false	},
    190 		{ "rgb5_a1",				GL_RGB5_A1,				false	},
    191 		{ "rgba8",					GL_RGBA8,				false	},
    192 		{ "rgb10_a2",				GL_RGB10_A2,			false	},
    193 		{ "rgb10_a2ui",				GL_RGB10_A2UI,			true	},
    194 		{ "srgb8_alpha8",			GL_SRGB8_ALPHA8,		false	},
    195 		{ "r8i",					GL_R8I,					true	},
    196 		{ "r8ui",					GL_R8UI,				true	},
    197 		{ "r16i",					GL_R16I,				true	},
    198 		{ "r16ui",					GL_R16UI,				true	},
    199 		{ "r32i",					GL_R32I,				true	},
    200 		{ "r32ui",					GL_R32UI,				true	},
    201 		{ "rg8i",					GL_RG8I,				true	},
    202 		{ "rg8ui",					GL_RG8UI,				true	},
    203 		{ "rg16i",					GL_RG16I,				true	},
    204 		{ "rg16ui",					GL_RG16UI,				true	},
    205 		{ "rg32i",					GL_RG32I,				true	},
    206 		{ "rg32ui",					GL_RG32UI,				true	},
    207 		{ "rgba8i",					GL_RGBA8I,				true	},
    208 		{ "rgba8ui",				GL_RGBA8UI,				true	},
    209 		{ "rgba16i",				GL_RGBA16I,				true	},
    210 		{ "rgba16ui",				GL_RGBA16UI,			true	},
    211 		{ "rgba32i",				GL_RGBA32I,				true	},
    212 		{ "rgba32ui",				GL_RGBA32UI,			true	},
    213 
    214 		// depth renderable
    215 		{ "depth_component16",		GL_DEPTH_COMPONENT16,	false	},
    216 		{ "depth_component24",		GL_DEPTH_COMPONENT24,	false	},
    217 		{ "depth_component32f",		GL_DEPTH_COMPONENT32F,	false	},
    218 		{ "depth24_stencil8",		GL_DEPTH24_STENCIL8,	false	},
    219 		{ "depth32f_stencil8",		GL_DEPTH32F_STENCIL8,	false	},
    220 
    221 		// stencil renderable
    222 		{ "stencil_index8",			GL_STENCIL_INDEX8,		false	}
    223 		// DEPTH24_STENCIL8,  duplicate
    224 		// DEPTH32F_STENCIL8  duplicate
    225 	};
    226 
    227 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(internalFormats); ++ndx)
    228 	{
    229 		const InternalFormat internalFormat = internalFormats[ndx];
    230 
    231 		addChild(new SamplesCase(m_context, (std::string(internalFormat.name) + "_samples").c_str(), "SAMPLES and NUM_SAMPLE_COUNTS", internalFormat.format, internalFormat.isIntegerFormat));
    232 	}
    233 
    234 	addChild(new SamplesBufferSizeCase(m_context, "rgba8_samples_buffer", "SAMPLES bufSize parameter", GL_RGBA8));
    235 }
    236 
    237 } // Functional
    238 } // gles3
    239 } // deqp
    240