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 32using namespace glw; // GLint and other GL types 33using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard; 34 35namespace deqp 36{ 37namespace gles3 38{ 39namespace Functional 40{ 41namespace 42{ 43 44class SamplesCase : public ApiCase 45{ 46public: 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 126private: 127 GLenum m_internalFormat; 128 bool m_isIntegerInternalFormat; 129}; 130 131class SamplesBufferSizeCase : public ApiCase 132{ 133public: 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 164private: 165 GLenum m_internalFormat; 166}; 167 168} // anonymous 169 170 171InternalFormatQueryTests::InternalFormatQueryTests (Context& context) 172 : TestCaseGroup(context, "internal_format", "Internal Format Query tests.") 173{ 174} 175 176void 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