| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES 3.0 Module |
| * ------------------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Internal Format Query tests. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "es3fInternalFormatQueryTests.hpp" |
| #include "glsStateQueryUtil.hpp" |
| #include "es3fApiCase.hpp" |
| #include "gluRenderContext.hpp" |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| #include "deMath.h" |
| |
| using namespace glw; // GLint and other GL types |
| using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard; |
| |
| namespace deqp |
| { |
| namespace gles3 |
| { |
| namespace Functional |
| { |
| namespace |
| { |
| |
| class SamplesCase : public ApiCase |
| { |
| public: |
| SamplesCase(Context& context, const char* name, const char* description, GLenum internalFormat, bool isIntegerInternalFormat) |
| : ApiCase (context, name, description) |
| , m_internalFormat (internalFormat) |
| , m_isIntegerInternalFormat (isIntegerInternalFormat) |
| { |
| } |
| |
| void test (void) |
| { |
| using tcu::TestLog; |
| |
| StateQueryMemoryWriteGuard<GLint> sampleCounts; |
| glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCounts); |
| expectError(GL_NO_ERROR); |
| |
| if (!sampleCounts.verifyValidity(m_testCtx)) |
| return; |
| |
| m_testCtx.getLog() << TestLog::Message << "// sample counts is " << sampleCounts << TestLog::EndMessage; |
| |
| if (sampleCounts == 0) |
| return; |
| |
| std::vector<GLint> samples; |
| samples.resize(sampleCounts, -1); |
| glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_SAMPLES, sampleCounts, &samples[0]); |
| expectError(GL_NO_ERROR); |
| |
| GLint prevSampleCount = 0; |
| GLint sampleCount = 0; |
| for (size_t ndx = 0; ndx < samples.size(); ++ndx, prevSampleCount = sampleCount) |
| { |
| sampleCount = samples[ndx]; |
| |
| // sample count must be > 0 |
| if (sampleCount <= 0) |
| { |
| m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected sample count to be at least one; got " << sampleCount << TestLog::EndMessage; |
| if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value"); |
| } |
| |
| // samples must be ordered descending |
| if (ndx != 0 && !(sampleCount < prevSampleCount)) |
| { |
| m_testCtx.getLog() << TestLog::Message |
| << "// ERROR: Expected sample count to be ordered in descending order;" |
| << "got " << prevSampleCount << " at index " << (ndx - 1) << ", and " << sampleCount << " at index " << ndx << TestLog::EndMessage; |
| if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid order"); |
| } |
| } |
| |
| if (!m_isIntegerInternalFormat) |
| { |
| // the maximum value in SAMPLES is guaranteed to be at least the value of MAX_SAMPLES |
| StateQueryMemoryWriteGuard<GLint> maxSamples; |
| glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); |
| expectError(GL_NO_ERROR); |
| |
| if (maxSamples.verifyValidity(m_testCtx)) |
| { |
| const GLint maximumFormatSampleCount = samples[0]; |
| if (!(maximumFormatSampleCount >= maxSamples)) |
| { |
| m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected maximum value in SAMPLES (" << maximumFormatSampleCount << ") to be at least the value of MAX_SAMPLES (" << maxSamples << ")" << TestLog::EndMessage; |
| if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid maximum sample count"); |
| } |
| } |
| } |
| } |
| |
| private: |
| const GLenum m_internalFormat; |
| const bool m_isIntegerInternalFormat; |
| }; |
| |
| class SamplesBufferSizeCase : public ApiCase |
| { |
| public: |
| SamplesBufferSizeCase(Context& context, const char* name, const char* description, GLenum internalFormat) |
| : ApiCase (context, name, description) |
| , m_internalFormat (internalFormat) |
| { |
| } |
| |
| void test (void) |
| { |
| using tcu::TestLog; |
| |
| StateQueryMemoryWriteGuard<GLint> sampleCounts; |
| glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCounts); |
| expectError(GL_NO_ERROR); |
| |
| if (!sampleCounts.verifyValidity(m_testCtx)) |
| return; |
| |
| // test with bufSize = 0 |
| GLint queryTargetValue = -1; |
| glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 0, &queryTargetValue); |
| expectError(GL_NO_ERROR); |
| |
| if (queryTargetValue != -1) |
| { |
| m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected output variable not to be written to." << TestLog::EndMessage; |
| if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid write"); |
| } |
| } |
| |
| private: |
| GLenum m_internalFormat; |
| }; |
| |
| } // anonymous |
| |
| |
| InternalFormatQueryTests::InternalFormatQueryTests (Context& context) |
| : TestCaseGroup(context, "internal_format", "Internal Format Query tests.") |
| { |
| } |
| |
| void InternalFormatQueryTests::init (void) |
| { |
| const struct InternalFormat |
| { |
| const char* name; |
| GLenum format; |
| bool isIntegerFormat; |
| } internalFormats[] = |
| { |
| // color renderable and unsized |
| // \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) |
| { "rgba", GL_RGBA, false }, |
| { "rgb", GL_RGB, false }, |
| |
| // color renderable |
| { "r8", GL_R8, false }, |
| { "rg8", GL_RG8, false }, |
| { "rgb8", GL_RGB8, false }, |
| { "rgb565", GL_RGB565, false }, |
| { "rgba4", GL_RGBA4, false }, |
| { "rgb5_a1", GL_RGB5_A1, false }, |
| { "rgba8", GL_RGBA8, false }, |
| { "rgb10_a2", GL_RGB10_A2, false }, |
| { "rgb10_a2ui", GL_RGB10_A2UI, true }, |
| { "srgb8_alpha8", GL_SRGB8_ALPHA8, false }, |
| { "r8i", GL_R8I, true }, |
| { "r8ui", GL_R8UI, true }, |
| { "r16i", GL_R16I, true }, |
| { "r16ui", GL_R16UI, true }, |
| { "r32i", GL_R32I, true }, |
| { "r32ui", GL_R32UI, true }, |
| { "rg8i", GL_RG8I, true }, |
| { "rg8ui", GL_RG8UI, true }, |
| { "rg16i", GL_RG16I, true }, |
| { "rg16ui", GL_RG16UI, true }, |
| { "rg32i", GL_RG32I, true }, |
| { "rg32ui", GL_RG32UI, true }, |
| { "rgba8i", GL_RGBA8I, true }, |
| { "rgba8ui", GL_RGBA8UI, true }, |
| { "rgba16i", GL_RGBA16I, true }, |
| { "rgba16ui", GL_RGBA16UI, true }, |
| { "rgba32i", GL_RGBA32I, true }, |
| { "rgba32ui", GL_RGBA32UI, true }, |
| |
| // depth renderable |
| { "depth_component16", GL_DEPTH_COMPONENT16, false }, |
| { "depth_component24", GL_DEPTH_COMPONENT24, false }, |
| { "depth_component32f", GL_DEPTH_COMPONENT32F, false }, |
| { "depth24_stencil8", GL_DEPTH24_STENCIL8, false }, |
| { "depth32f_stencil8", GL_DEPTH32F_STENCIL8, false }, |
| |
| // stencil renderable |
| { "stencil_index8", GL_STENCIL_INDEX8, false } |
| // DEPTH24_STENCIL8, duplicate |
| // DEPTH32F_STENCIL8 duplicate |
| }; |
| |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(internalFormats); ++ndx) |
| { |
| const InternalFormat internalFormat = internalFormats[ndx]; |
| |
| addChild(new SamplesCase(m_context, (std::string(internalFormat.name) + "_samples").c_str(), "SAMPLES and NUM_SAMPLE_COUNTS", internalFormat.format, internalFormat.isIntegerFormat)); |
| } |
| |
| addChild(new SamplesBufferSizeCase(m_context, "rgba8_samples_buffer", "SAMPLES bufSize parameter", GL_RGBA8)); |
| } |
| |
| } // Functional |
| } // gles3 |
| } // deqp |