| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2017 The Khronos Group Inc. |
| * |
| * 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 glcPackedDepthStencilTests.cpp |
| * \brief |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "glcPackedDepthStencilTests.hpp" |
| #include "deMath.h" |
| #include "gluContextInfo.hpp" |
| #include "gluDrawUtil.hpp" |
| #include "gluRenderContext.hpp" |
| #include "gluShaderProgram.hpp" |
| #include "gluStrUtil.hpp" |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "tcuTestLog.hpp" |
| #include <algorithm> |
| #include <cstring> |
| #include <stdio.h> |
| |
| using namespace glw; |
| using namespace glu; |
| |
| namespace glcts |
| { |
| |
| #define TEX_SIZE 256 |
| #define TOLERANCE_LOW 0.48 |
| #define TOLERANCE_HIGH 0.52 |
| #define EPSILON 0.01 |
| |
| enum DrawMode |
| { |
| DEFAULT, |
| DEPTH_SPAN1, |
| DEPTH_SPAN2, |
| }; |
| |
| struct D32F_S8 |
| { |
| GLfloat d; |
| GLuint s; |
| }; |
| |
| // Reference texture names for the described 5 textures and framebuffers |
| // and also for identifying other cases' reference textures |
| enum TextureNames |
| { |
| packedTexImage, |
| packedTexRender, |
| packedTexRenderInitStencil, |
| packedTexRenderDepthStep, |
| packedTexRenderStencilStep, |
| NUM_TEXTURES, |
| verifyCopyTexImage, |
| verifyPartialAttachments, |
| verifyMixedAttachments, |
| verifyClearBufferDepth, |
| verifyClearBufferStencil, |
| verifyClearBufferDepthStencil, |
| verifyBlit, |
| }; |
| |
| struct TypeFormat |
| { |
| GLenum type; |
| GLenum format; |
| const char* formatName; |
| int size; |
| int d; |
| int s; |
| }; |
| |
| #define NUM_TEXTURE_TYPES 2 |
| |
| static const TypeFormat TextureTypes[NUM_TEXTURE_TYPES] = { |
| { GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8, "depth24_stencil8", sizeof(GLuint), 24, 8 }, |
| { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8, "depth32f_stencil8", sizeof(GLuint) + sizeof(GLfloat), |
| 32, 8 }, |
| }; |
| |
| // Texture targets for initial state checking |
| static const GLenum coreTexTargets[] = { |
| GL_TEXTURE_2D, |
| GL_TEXTURE_3D, |
| GL_TEXTURE_2D_ARRAY, |
| GL_TEXTURE_CUBE_MAP_POSITIVE_X, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_X, |
| GL_TEXTURE_CUBE_MAP_POSITIVE_Y, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, |
| GL_TEXTURE_CUBE_MAP_POSITIVE_Z, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, |
| GL_TEXTURE_1D, |
| GL_TEXTURE_1D_ARRAY, |
| GL_TEXTURE_CUBE_MAP_ARRAY, |
| GL_TEXTURE_RECTANGLE, |
| GL_TEXTURE_2D_MULTISAMPLE, |
| GL_TEXTURE_2D_MULTISAMPLE_ARRAY, |
| GL_PROXY_TEXTURE_1D, |
| GL_PROXY_TEXTURE_2D, |
| GL_PROXY_TEXTURE_3D, |
| GL_PROXY_TEXTURE_1D_ARRAY, |
| GL_PROXY_TEXTURE_2D_ARRAY, |
| GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, |
| GL_PROXY_TEXTURE_RECTANGLE, |
| GL_PROXY_TEXTURE_CUBE_MAP, |
| GL_PROXY_TEXTURE_2D_MULTISAMPLE, |
| GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, |
| }; |
| static const GLenum esTexTargets[] = { |
| GL_TEXTURE_2D, |
| GL_TEXTURE_3D, |
| GL_TEXTURE_2D_ARRAY, |
| GL_TEXTURE_CUBE_MAP_POSITIVE_X, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_X, |
| GL_TEXTURE_CUBE_MAP_POSITIVE_Y, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, |
| GL_TEXTURE_CUBE_MAP_POSITIVE_Z, |
| GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, |
| }; |
| |
| // Listing of non-depth_stencil types for error tests |
| static const GLenum coreNonDepthStencilTypes[] = { |
| GL_UNSIGNED_BYTE, |
| GL_BYTE, |
| GL_UNSIGNED_SHORT, |
| GL_SHORT, |
| GL_UNSIGNED_INT, |
| GL_INT, |
| GL_HALF_FLOAT, |
| GL_FLOAT, |
| GL_UNSIGNED_SHORT_5_6_5, |
| GL_UNSIGNED_SHORT_4_4_4_4, |
| GL_UNSIGNED_SHORT_5_5_5_1, |
| GL_UNSIGNED_INT_2_10_10_10_REV, |
| GL_UNSIGNED_INT_10F_11F_11F_REV, |
| GL_UNSIGNED_INT_5_9_9_9_REV, |
| GL_UNSIGNED_BYTE_3_3_2, |
| GL_UNSIGNED_BYTE_2_3_3_REV, |
| GL_UNSIGNED_SHORT_5_6_5_REV, |
| GL_UNSIGNED_SHORT_4_4_4_4_REV, |
| GL_UNSIGNED_SHORT_1_5_5_5_REV, |
| GL_UNSIGNED_INT_8_8_8_8, |
| GL_UNSIGNED_INT_8_8_8_8_REV, |
| GL_UNSIGNED_INT_10_10_10_2, |
| }; |
| static const GLenum esNonDepthStencilTypes[] = { |
| GL_UNSIGNED_BYTE, |
| GL_BYTE, |
| GL_UNSIGNED_SHORT, |
| GL_SHORT, |
| GL_UNSIGNED_INT, |
| GL_INT, |
| GL_HALF_FLOAT, |
| GL_FLOAT, |
| GL_UNSIGNED_SHORT_5_6_5, |
| GL_UNSIGNED_SHORT_4_4_4_4, |
| GL_UNSIGNED_SHORT_5_5_5_1, |
| GL_UNSIGNED_INT_2_10_10_10_REV, |
| GL_UNSIGNED_INT_10F_11F_11F_REV, |
| GL_UNSIGNED_INT_5_9_9_9_REV, |
| }; |
| |
| // Listing of non-depth_stencil formats for error tests |
| static const GLenum coreNonDepthStencilFormats[] = { |
| GL_STENCIL_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_RG, GL_RGB, GL_RGBA, |
| GL_BGR, GL_BGRA, GL_RED_INTEGER, GL_GREEN_INTEGER, GL_BLUE_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, |
| GL_RGBA_INTEGER, GL_BGR_INTEGER, GL_BGRA_INTEGER, |
| }; |
| static const GLenum esNonDepthStencilFormats[] = { |
| GL_RED, |
| GL_RG, |
| GL_RGB, |
| GL_RGBA, |
| GL_LUMINANCE, // for es3+ |
| GL_ALPHA, // for es3+ |
| GL_LUMINANCE_ALPHA, // for es3+ |
| GL_RED_INTEGER, |
| GL_RG_INTEGER, |
| GL_RGB_INTEGER, |
| GL_RGBA_INTEGER, |
| }; |
| |
| // Listing of non-depth_stencil base formats for error tests |
| static const GLenum coreOtherBaseFormats[] = { |
| GL_RED, GL_RG, GL_RGB, GL_RGBA, |
| }; |
| static const GLenum esOtherBaseFormats[] = { |
| GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_ALPHA, GL_LUMINANCE_ALPHA, |
| }; |
| |
| struct AttachmentParam |
| { |
| GLenum pname; |
| GLint value; |
| }; |
| |
| #define NUM_ATTACHMENT_PARAMS_CORE 13 |
| #define NUM_ATTACHMENT_PARAMS_ES 12 |
| |
| static const AttachmentParam coreAttachmentParams[NUM_TEXTURE_TYPES][NUM_ATTACHMENT_PARAMS_CORE] = { |
| { |
| { GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 24 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_UNSIGNED_NORMALIZED }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR }, |
| { GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 0 }, |
| }, |
| { |
| { GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 32 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FLOAT }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR }, |
| { GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 0 }, |
| }, |
| }; |
| static const AttachmentParam esAttachmentParams[NUM_TEXTURE_TYPES][NUM_ATTACHMENT_PARAMS_ES] = { |
| { |
| { GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 24 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_UNSIGNED_NORMALIZED }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR }, |
| { GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 }, |
| }, |
| { |
| { GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 32 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FLOAT }, |
| { GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR }, |
| { GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 }, |
| { GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 }, |
| }, |
| }; |
| |
| enum ColorFunction |
| { |
| COLOR_CHECK_DEFAULT, |
| COLOR_CHECK_DEPTH, |
| COLOR_CHECK_STENCIL, |
| }; |
| |
| class BaseTest : public deqp::TestCase |
| { |
| public: |
| BaseTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~BaseTest(); |
| |
| void init(void); |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| const AttachmentParam* getAttachmentParams() const; |
| void createGradient(std::vector<GLbyte>& data); |
| |
| void setDrawReadBuffer(GLenum draw, GLenum read); |
| void restoreDrawReadBuffer(); |
| |
| void createTextures(); |
| void setupTexture(); |
| void destroyTextures(); |
| |
| GLuint createProgram(const char* vsCode, const char* fsCode); |
| void setupColorProgram(GLint& uColor); |
| bool setupTextureProgram(); |
| bool setupStencilProgram(); |
| bool setTextureUniform(GLuint programId); |
| |
| void drawQuad(DrawMode drawMode, GLuint program); |
| void renderToTextures(); |
| bool verifyDepthStencilGradient(GLvoid* data, unsigned int texIndex, int width, int height); |
| bool verifyColorGradient(GLvoid* data, unsigned int texIndex, int function, int width, int height); |
| bool doReadPixels(GLuint texture, int function); |
| |
| protected: |
| GLuint m_defaultFBO; |
| GLuint m_drawBuffer; |
| GLuint m_readBuffer; |
| |
| const GLenum* m_textureTargets; |
| GLuint m_textureTargetsCount; |
| const GLenum* m_nonDepthStencilTypes; |
| GLuint m_nonDepthStencilTypesCount; |
| const GLenum* m_nonDepthStencilFormats; |
| GLuint m_nonDepthStencilFormatsCount; |
| const GLenum* m_otherBaseFormats; |
| GLuint m_otherBaseFormatsCount; |
| |
| const AttachmentParam* m_attachmentParams[NUM_TEXTURE_TYPES]; |
| GLuint m_attachmentParamsCount; |
| |
| const TypeFormat& m_typeFormat; |
| |
| GLuint m_textureProgram; |
| GLuint m_colorProgram; |
| GLuint m_stencilProgram; |
| |
| GLuint m_textures[NUM_TEXTURES]; |
| GLuint m_framebuffers[NUM_TEXTURES]; |
| }; |
| |
| BaseTest::BaseTest(deqp::Context& context, const TypeFormat& tf) |
| : deqp::TestCase(context, tf.formatName, "") |
| , m_defaultFBO(0) |
| , m_drawBuffer(GL_COLOR_ATTACHMENT0) |
| , m_readBuffer(GL_COLOR_ATTACHMENT0) |
| , m_textureTargets(coreTexTargets) |
| , m_textureTargetsCount(DE_LENGTH_OF_ARRAY(coreTexTargets)) |
| , m_nonDepthStencilTypes(coreNonDepthStencilTypes) |
| , m_nonDepthStencilTypesCount(DE_LENGTH_OF_ARRAY(coreNonDepthStencilTypes)) |
| , m_nonDepthStencilFormats(coreNonDepthStencilFormats) |
| , m_nonDepthStencilFormatsCount(DE_LENGTH_OF_ARRAY(coreNonDepthStencilFormats)) |
| , m_otherBaseFormats(coreOtherBaseFormats) |
| , m_otherBaseFormatsCount(DE_LENGTH_OF_ARRAY(coreOtherBaseFormats)) |
| , m_attachmentParamsCount(0) |
| , m_typeFormat(tf) |
| , m_textureProgram(0) |
| , m_colorProgram(0) |
| , m_stencilProgram(0) |
| |
| { |
| } |
| |
| BaseTest::~BaseTest() |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| if (m_textureProgram) |
| gl.deleteProgram(m_textureProgram); |
| if (m_colorProgram) |
| gl.deleteProgram(m_colorProgram); |
| if (m_stencilProgram) |
| gl.deleteProgram(m_stencilProgram); |
| } |
| |
| void BaseTest::init(void) |
| { |
| if (glu::isContextTypeES(m_context.getRenderContext().getType())) |
| { |
| m_textureTargets = esTexTargets; |
| m_textureTargetsCount = DE_LENGTH_OF_ARRAY(esTexTargets); |
| m_nonDepthStencilTypes = esNonDepthStencilTypes; |
| m_nonDepthStencilTypesCount = DE_LENGTH_OF_ARRAY(esNonDepthStencilTypes); |
| m_nonDepthStencilFormats = esNonDepthStencilFormats; |
| m_nonDepthStencilFormatsCount = DE_LENGTH_OF_ARRAY(esNonDepthStencilFormats); |
| m_otherBaseFormats = esOtherBaseFormats; |
| m_otherBaseFormatsCount = DE_LENGTH_OF_ARRAY(esOtherBaseFormats); |
| |
| for (int i = 0; i < NUM_TEXTURE_TYPES; i++) |
| m_attachmentParams[i] = esAttachmentParams[i]; |
| m_attachmentParamsCount = NUM_ATTACHMENT_PARAMS_ES; |
| } |
| else |
| { |
| for (int i = 0; i < NUM_TEXTURE_TYPES; i++) |
| m_attachmentParams[i] = coreAttachmentParams[i]; |
| m_attachmentParamsCount = NUM_ATTACHMENT_PARAMS_CORE; |
| } |
| } |
| |
| tcu::TestNode::IterateResult BaseTest::iterate(void) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| return STOP; |
| } |
| |
| const AttachmentParam* BaseTest::getAttachmentParams() const |
| { |
| // find type index |
| int index = 0; |
| for (; index < NUM_TEXTURE_TYPES; index++) |
| { |
| if (TextureTypes[index].format == m_typeFormat.format) |
| break; |
| } |
| |
| if (index >= NUM_TEXTURE_TYPES) |
| TCU_FAIL("Missing attachment definition"); |
| |
| return m_attachmentParams[index]; |
| } |
| |
| // Creates a gradient texture data in the given type parameter format |
| void BaseTest::createGradient(std::vector<GLbyte>& data) |
| { |
| switch (m_typeFormat.type) |
| { |
| case GL_UNSIGNED_INT_24_8: |
| { |
| data.resize(TEX_SIZE * TEX_SIZE * sizeof(GLuint)); |
| GLuint* dataPtr = reinterpret_cast<GLuint*>(&data[0]); |
| for (int j = 0; j < TEX_SIZE; j++) |
| { |
| for (int i = 0; i < TEX_SIZE; i++) |
| { |
| GLuint d = static_cast<GLuint>(static_cast<float>(i) / (TEX_SIZE - 1) * 0x00ffffff); |
| GLubyte s = i & 0xff; |
| |
| dataPtr[TEX_SIZE * j + i] = (d << 8) + s; |
| } |
| } |
| return; |
| } |
| case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: |
| { |
| data.resize(TEX_SIZE * TEX_SIZE * sizeof(D32F_S8)); |
| D32F_S8* dataPtr = reinterpret_cast<D32F_S8*>(&data[0]); |
| for (int j = 0; j < TEX_SIZE; j++) |
| { |
| for (int i = 0; i < TEX_SIZE; i++) |
| { |
| D32F_S8 v = { static_cast<float>(i) / (TEX_SIZE - 1), static_cast<GLuint>(i & 0xff) }; |
| dataPtr[TEX_SIZE * j + i] = v; |
| } |
| } |
| return; |
| } |
| default: |
| TCU_FAIL("Unsuported type"); |
| } |
| } |
| |
| void BaseTest::setDrawReadBuffer(GLenum draw, GLenum read) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| GLint drawBuffer; |
| gl.getIntegerv(GL_DRAW_BUFFER0, &drawBuffer); |
| m_drawBuffer = static_cast<GLuint>(drawBuffer); |
| |
| GLint readBuffer; |
| gl.getIntegerv(GL_READ_BUFFER, &readBuffer); |
| m_readBuffer = static_cast<GLuint>(readBuffer); |
| |
| gl.drawBuffers(1, &draw); |
| gl.readBuffer(read); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer"); |
| } |
| |
| void BaseTest::restoreDrawReadBuffer() |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| gl.drawBuffers(1, &m_drawBuffer); |
| gl.readBuffer(m_readBuffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer"); |
| } |
| |
| void BaseTest::createTextures() |
| { |
| // Creates all the textures and framebuffers |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genTextures(NUM_TEXTURES, m_textures); |
| gl.genFramebuffers(NUM_TEXTURES, m_framebuffers); |
| |
| // packedTexImage |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]); |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]); |
| setupTexture(); |
| std::vector<GLbyte> data; |
| createGradient(data); |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, |
| &data[0]); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0); |
| |
| // packedTexRender |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]); |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRender]); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, |
| NULL); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRender], 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRender], 0); |
| |
| // packedTexRenderInitStencil |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderInitStencil]); |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderInitStencil]); |
| setupTexture(); |
| createGradient(data); |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, |
| &data[0]); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderInitStencil], |
| 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, |
| m_textures[packedTexRenderInitStencil], 0); |
| |
| // packedTexRenderDepthStep |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderDepthStep]); |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep]); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, |
| NULL); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep], |
| 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep], |
| 0); |
| |
| // packedTexRenderStencilStep |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderStencilStep]); |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderStencilStep]); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, |
| NULL); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderStencilStep], |
| 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, |
| m_textures[packedTexRenderStencilStep], 0); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer"); |
| } |
| |
| void BaseTest::setupTexture() |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); |
| } |
| |
| // Destroys all the textures and framebuffers |
| void BaseTest::destroyTextures() |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| gl.deleteFramebuffers(NUM_TEXTURES, m_framebuffers); |
| gl.deleteTextures(NUM_TEXTURES, m_textures); |
| } |
| |
| GLuint BaseTest::createProgram(const char* vsCode, const char* fsCode) |
| { |
| glu::RenderContext& renderContext = m_context.getRenderContext(); |
| glu::ContextType contextType = renderContext.getType(); |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType); |
| const char* version = glu::getGLSLVersionDeclaration(glslVersion); |
| |
| glu::Shader vs(gl, glu::SHADERTYPE_VERTEX); |
| const char* vSources[] = { version, vsCode }; |
| const int vLengths[] = { int(strlen(version)), int(strlen(vsCode)) }; |
| vs.setSources(2, vSources, vLengths); |
| vs.compile(); |
| if (!vs.getCompileStatus()) |
| TCU_FAIL("Vertex shader compilation failed"); |
| |
| glu::Shader fs(gl, glu::SHADERTYPE_FRAGMENT); |
| const char* fSources[] = { version, fsCode }; |
| const int fLengths[] = { int(strlen(version)), int(strlen(fsCode)) }; |
| fs.setSources(2, fSources, fLengths); |
| fs.compile(); |
| if (!fs.getCompileStatus()) |
| TCU_FAIL("Fragment shader compilation failed"); |
| |
| GLuint p = gl.createProgram(); |
| gl.attachShader(p, vs.getShader()); |
| gl.attachShader(p, fs.getShader()); |
| gl.linkProgram(p); |
| return p; |
| } |
| |
| void BaseTest::setupColorProgram(GLint& uColor) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| const char* vs = "\n" |
| "precision highp float;\n" |
| "in vec4 pos;\n" |
| "void main() {\n" |
| " gl_Position = pos;\n" |
| "}\n"; |
| |
| const char* fs = "\n" |
| "precision highp float;\n" |
| "out vec4 color;\n" |
| "uniform vec4 uColor;\n" |
| "void main() {\n" |
| " color = uColor;\n" |
| "}\n"; |
| |
| // setup shader program |
| if (!m_colorProgram) |
| m_colorProgram = createProgram(vs, fs); |
| if (!m_colorProgram) |
| TCU_FAIL("Error while loading shader program"); |
| |
| gl.useProgram(m_colorProgram); |
| |
| // Setup program uniforms |
| uColor = gl.getUniformLocation(m_colorProgram, "uColor"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation"); |
| |
| if (uColor == -1) |
| TCU_FAIL("Error getting uniform uColor"); |
| |
| gl.uniform4f(uColor, 1.0f, 1.0f, 1.0f, 1.0f); |
| } |
| |
| // Common code for default and stencil texture rendering shaders |
| bool BaseTest::setTextureUniform(GLuint programId) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.useProgram(programId); |
| |
| GLint uniformTex = gl.getUniformLocation(programId, "tex"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation"); |
| |
| if (uniformTex == -1) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Error getting uniform tex" << tcu::TestLog::EndMessage; |
| return false; |
| } |
| |
| gl.uniform1i(uniformTex, 0); |
| return true; |
| } |
| |
| // Loads texture rendering shader |
| bool BaseTest::setupTextureProgram() |
| { |
| const char* vs = "\n" |
| "precision highp float;\n" |
| "in vec4 pos;\n" |
| "in vec2 UV;\n" |
| "out vec2 vUV;\n" |
| "void main() {\n" |
| " gl_Position = pos;\n" |
| " vUV = UV;\n" |
| "}\n"; |
| |
| const char* fs = "\n" |
| "precision highp float;\n" |
| "in vec2 vUV;\n" |
| "out vec4 color;\n" |
| "uniform sampler2D tex;\n" |
| "void main() {\n" |
| " color = texture(tex, vUV).rrra;\n" |
| "}\n"; |
| |
| if (!m_textureProgram) |
| m_textureProgram = createProgram(vs, fs); |
| if (!m_textureProgram) |
| return false; |
| |
| return setTextureUniform(m_textureProgram); |
| } |
| |
| // Loads texture stencil rendering shader |
| bool BaseTest::setupStencilProgram() |
| { |
| const char* vs = "\n" |
| "precision highp float;\n" |
| "in vec4 pos;\n" |
| "in vec2 UV;\n" |
| "out vec2 vUV;\n" |
| "void main() {\n" |
| " gl_Position = pos;\n" |
| " vUV = UV;\n" |
| "}\n"; |
| |
| const char* fs = "\n" |
| "precision highp float;\n" |
| "in vec2 vUV;\n" |
| "out vec4 color;\n" |
| "uniform highp usampler2D tex;\n" |
| "void main() {\n" |
| " float s = float(texture(tex, vUV).r);\n" |
| " s /= 255.0;\n" |
| " color = vec4(s, s, s, 1);\n" |
| "}\n"; |
| |
| if (!m_stencilProgram) |
| m_stencilProgram = createProgram(vs, fs); |
| if (!m_stencilProgram) |
| return false; |
| |
| return setTextureUniform(m_stencilProgram); |
| } |
| |
| void BaseTest::drawQuad(DrawMode drawMode, GLuint program) |
| { |
| static const GLfloat verticesDefault[] = { |
| -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, |
| }; |
| |
| static const GLfloat verticesDepthSpan1[] = { |
| -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, |
| }; |
| |
| static const GLfloat verticesDepthSpan2[] = { |
| -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, |
| }; |
| |
| static const GLfloat texCoords[] = { |
| 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, |
| }; |
| |
| static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 }; |
| static PrimitiveList quadPrimitive = glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices); |
| |
| static const glu::VertexArrayBinding depthSpanVA1[] = { glu::va::Float("pos", 4, 4, 0, verticesDepthSpan1) }; |
| static const glu::VertexArrayBinding depthSpanVA2[] = { glu::va::Float("pos", 4, 4, 0, verticesDepthSpan2) }; |
| static const glu::VertexArrayBinding defaultVA[] = { glu::va::Float("pos", 4, 4, 0, verticesDefault), |
| glu::va::Float("UV", 2, 4, 0, texCoords) }; |
| |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| if (drawMode == DEPTH_SPAN1) |
| glu::draw(renderContext, program, 1, depthSpanVA1, quadPrimitive); |
| else if (drawMode == DEPTH_SPAN2) |
| glu::draw(renderContext, program, 1, depthSpanVA2, quadPrimitive); |
| else |
| glu::draw(renderContext, program, 2, defaultVA, quadPrimitive); |
| } |
| |
| // Renders all non-trivial startup textures |
| void BaseTest::renderToTextures() |
| { |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| const glw::Functions& gl = renderContext.getFunctions(); |
| |
| GLint uColor; |
| setupColorProgram(uColor); |
| |
| gl.enable(GL_DEPTH_TEST); |
| // depth writing must be enabled as it is disabled in places like doReadPixels |
| gl.depthMask(GL_TRUE); |
| |
| if (glu::isContextTypeES(renderContext.getType())) |
| gl.clearDepthf(1.0f); |
| else |
| gl.clearDepth(1.0); |
| |
| gl.depthFunc(GL_LEQUAL); |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| |
| drawQuad(DEPTH_SPAN1, m_colorProgram); |
| |
| // packedTexRender |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]); |
| |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| gl.enable(GL_STENCIL_TEST); |
| gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF); |
| gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR); |
| |
| gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| drawQuad(DEPTH_SPAN1, m_colorProgram); |
| |
| gl.disable(GL_STENCIL_TEST); |
| |
| restoreDrawReadBuffer(); |
| |
| // packedTexRenderInitStencil |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderInitStencil]); |
| |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| gl.clear(GL_DEPTH_BUFFER_BIT); |
| drawQuad(DEPTH_SPAN1, m_colorProgram); |
| |
| restoreDrawReadBuffer(); |
| |
| // packedTexRenderDepthStep |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderDepthStep]); |
| |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| drawQuad(DEPTH_SPAN2, m_colorProgram); |
| drawQuad(DEPTH_SPAN1, m_colorProgram); |
| |
| restoreDrawReadBuffer(); |
| |
| // packedTexRenderStencilStep |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderStencilStep]); |
| |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| gl.enable(GL_SCISSOR_TEST); |
| gl.scissor(0, 0, TEX_SIZE, TEX_SIZE / 2); |
| |
| gl.enable(GL_STENCIL_TEST); |
| gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF); |
| gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR); |
| for (int i = 0; i < 256; i++) |
| drawQuad(DEPTH_SPAN2, m_colorProgram); |
| gl.disable(GL_SCISSOR_TEST); |
| |
| gl.stencilFunc(GL_EQUAL, 0xFF, 0xFF); |
| gl.clear(GL_DEPTH_BUFFER_BIT); |
| drawQuad(DEPTH_SPAN1, m_colorProgram); |
| gl.disable(GL_STENCIL_TEST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable"); |
| |
| restoreDrawReadBuffer(); |
| |
| // end |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer"); |
| } |
| |
| // Verifies DepthStencil buffer data against reference values |
| bool BaseTest::verifyDepthStencilGradient(GLvoid* data, unsigned int texIndex, int width, int height) |
| { |
| bool result = true; |
| |
| int index, skip; |
| int countD, countS; |
| |
| index = 0; |
| countD = 0; |
| countS = 0; |
| |
| for (int j = 0; j < height; j++) |
| { |
| for (int i = 0; i < width; i++) |
| { |
| float d, dref = 0.0; |
| int s, sref = 0; |
| |
| skip = 0; |
| |
| switch (m_typeFormat.type) |
| { |
| case GL_UNSIGNED_INT_24_8: |
| { |
| GLuint v = ((GLuint*)data)[index]; |
| d = ((float)(v >> 8)) / 0xffffff; |
| s = v & 0xff; |
| break; |
| } |
| case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: |
| { |
| D32F_S8 v = ((D32F_S8*)data)[index]; |
| d = v.d; |
| s = v.s & 0xff; |
| break; |
| } |
| default: |
| d = -1; |
| s = -1; |
| break; |
| } |
| |
| switch (texIndex) |
| { |
| case packedTexImage: |
| dref = ((float)i) / (width - 1); |
| sref = (int)(dref * 255); |
| break; |
| case packedTexRender: |
| dref = ((float)j) / (height - 1); |
| sref = 1; |
| break; |
| case packedTexRenderInitStencil: |
| dref = ((float)j) / (height - 1); |
| sref = (int)(((float)i) / (width - 1) * 255); |
| break; |
| case packedTexRenderDepthStep: |
| if (j < height * TOLERANCE_LOW) |
| { |
| dref = ((float)j) / (height - 1); |
| sref = 0; |
| } |
| else if (j > height * TOLERANCE_HIGH) |
| { |
| dref = 1.0f - ((float)j) / (height - 1); |
| sref = 0; |
| } |
| else |
| { |
| skip = 1; // give some tolerance to pixels in the middle |
| } |
| break; |
| case packedTexRenderStencilStep: |
| if (j < height * TOLERANCE_LOW) |
| { |
| dref = ((float)j) / (height - 1); |
| sref = 255; |
| } |
| else if (j > height * TOLERANCE_HIGH) |
| { |
| dref = 1; |
| sref = 0; |
| } |
| else |
| { |
| skip = 1; // give some tolerance to pixels in the middle |
| } |
| break; |
| case verifyCopyTexImage: |
| if (j < height * TOLERANCE_LOW) |
| { |
| dref = ((float)j) / (height - 1); |
| sref = 1; |
| } |
| else if (j > height * TOLERANCE_HIGH) |
| { |
| dref = 0.5; |
| sref = 1; |
| } |
| else |
| { |
| skip = 1; // give some tolerance to pixels in the middle |
| } |
| break; |
| default: |
| dref = -2; |
| sref = -2; |
| break; |
| } |
| |
| if (!skip) |
| { |
| if (deFloatAbs(d - dref) > EPSILON) |
| { |
| result = false; |
| countD++; |
| } |
| |
| if (s != sref) |
| { |
| result = false; |
| countS++; |
| } |
| } |
| else |
| { |
| skip = 0; |
| } |
| |
| index++; |
| } |
| } |
| |
| if (countD || countS) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "DEPTH_STENCIL comparison failed" << tcu::TestLog::EndMessage; |
| } |
| return result; |
| } |
| |
| // Verifies Color buffer data against reference values |
| bool BaseTest::verifyColorGradient(GLvoid* data, unsigned int texIndex, int function, int width, int height) |
| { |
| bool result = true; |
| |
| int index = 0, skip; |
| int channel = 0; |
| int count = 0; |
| |
| for (int j = 0; j < height; j++) |
| { |
| for (int i = 0; i < width; i++) |
| { |
| skip = 0; |
| GLuint color = ((GLuint*)data)[index]; |
| GLuint colorref = 0; |
| |
| // When data back from glReadPixels with arguments GL_RGBA + GL_UNSIGNED_BYTE, |
| // we should reverse byte order in big-endian platform for (GLuint*) pointer. |
| #if (DE_ENDIANNESS == DE_BIG_ENDIAN) |
| color = deReverseBytes32(color); |
| #endif |
| |
| switch (texIndex) |
| { |
| case packedTexImage: |
| channel = (int)(((float)i) / (width - 1) * 255); |
| colorref = 0xff000000 + channel * 0x00010101; |
| break; |
| case packedTexRender: |
| if (function == COLOR_CHECK_DEPTH) |
| channel = (int)(((float)j) / (height - 1) * 255); |
| else |
| channel = 1; |
| colorref = 0xff000000 + channel * 0x00010101; |
| break; |
| case packedTexRenderInitStencil: |
| if (function == COLOR_CHECK_DEPTH) |
| channel = (int)(((float)j) / (height - 1) * 255); |
| else |
| channel = (int)(((float)i) / (width - 1) * 255); |
| colorref = 0xff000000 + channel * 0x00010101; |
| break; |
| case packedTexRenderDepthStep: |
| if (function == COLOR_CHECK_DEPTH) |
| { |
| if (j < height * TOLERANCE_LOW) |
| channel = (int)(((float)j) / (height - 1) * 255); |
| else if (j > height * TOLERANCE_HIGH) |
| channel = 255 - (int)(((float)j) / (height - 1) * 255); |
| else |
| skip = 1; // give some tolerance to pixels in the middle |
| } |
| else |
| channel = 0; |
| colorref = 0xff000000 + channel * 0x00010101; |
| break; |
| case packedTexRenderStencilStep: |
| if (j < height * TOLERANCE_LOW) |
| { |
| if (function == COLOR_CHECK_DEPTH) |
| channel = (int)(((float)j) / (height - 1) * 255); |
| else |
| channel = 255; |
| } |
| else if (j > height * TOLERANCE_HIGH) |
| channel = (function == COLOR_CHECK_DEPTH) ? 255 : 0; |
| else |
| skip = 1; // give some tolerance to pixels in the middle |
| colorref = 0xff000000 + channel * 0x00010101; |
| break; |
| case verifyCopyTexImage: |
| if (j < height * TOLERANCE_LOW) |
| { |
| if (function == COLOR_CHECK_DEPTH) |
| channel = (int)(((float)j) / (height - 1) * 255); |
| else |
| channel = 1; |
| } |
| else if (j > height * TOLERANCE_HIGH) |
| { |
| channel = (function == COLOR_CHECK_DEPTH) ? 127 : 1; |
| } |
| else |
| { |
| skip = 1; // give some tolerance to pixels in the middle |
| } |
| colorref = 0xff000000 + channel * 0x00010101; |
| break; |
| case verifyPartialAttachments: |
| colorref = 0xffffffff; |
| break; |
| case verifyMixedAttachments: |
| if (j > height * TOLERANCE_HIGH) |
| colorref = 0xffffffff; |
| else if (j < height * TOLERANCE_LOW) |
| colorref = 0xcccccccc; |
| else |
| skip = 1; |
| break; |
| case verifyClearBufferDepth: |
| if ((i & 0xff) == 0xff) |
| colorref = 0xffffffff; |
| else |
| colorref = 0xcccccccc; |
| break; |
| case verifyClearBufferStencil: |
| if (i > width * TOLERANCE_HIGH) |
| colorref = 0xffffffff; |
| else if (i < width * TOLERANCE_LOW) |
| colorref = 0xcccccccc; |
| else |
| skip = 1; |
| break; |
| case verifyClearBufferDepthStencil: |
| colorref = 0xffffffff; |
| break; |
| case verifyBlit: |
| if (j > height * TOLERANCE_HIGH) |
| colorref = 0xffffffff; |
| else if (j < height * TOLERANCE_LOW) |
| colorref = 0xcccccccc; |
| else |
| skip = 1; |
| break; |
| default: |
| colorref = 0xdeadbeef; |
| break; |
| } |
| |
| if (skip) |
| skip = 0; |
| else if (color != colorref) |
| { |
| float d = (float)(color & 0xff) / 0xff; |
| float dref = (float)(colorref & 0xff) / 0xff; |
| if (!((function == COLOR_CHECK_DEPTH) && (deFloatAbs(d - dref) < EPSILON))) |
| { |
| result = false; |
| count++; |
| } |
| } |
| |
| index++; |
| } |
| } |
| |
| if (count) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "*** Color comparison failed" << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| return result; |
| } |
| |
| // Verify DepthStencil texture by replicating it to color channels |
| // so it can be read using ReadPixels in Halti. |
| bool BaseTest::doReadPixels(GLuint texture, int function) |
| { |
| bool result = true; |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| GLuint fbo; |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| GLuint texColor; |
| gl.genTextures(1, &texColor); |
| gl.bindTexture(GL_TEXTURE_2D, texColor); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0); |
| setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0); |
| |
| // Step 1: Verify depth values |
| GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| else |
| { |
| setupTextureProgram(); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture); |
| |
| gl.disable(GL_DEPTH_TEST); |
| gl.depthMask(GL_FALSE); |
| gl.disable(GL_STENCIL_TEST); |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| drawQuad(DEFAULT, m_textureProgram); |
| |
| std::vector<GLuint> dataColor(TEX_SIZE * TEX_SIZE, 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]); |
| result &= verifyColorGradient(&dataColor[0], function, COLOR_CHECK_DEPTH, TEX_SIZE, TEX_SIZE); |
| |
| // Step 2: Verify stencil values |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0); |
| |
| status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| else |
| { |
| GLint uColor; |
| setupColorProgram(uColor); |
| |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| |
| gl.enable(GL_STENCIL_TEST); |
| for (int i = 0; i < 256; i++) |
| { |
| float v = i / 255.0f; |
| gl.uniform4f(uColor, v, v, v, 1.0f); |
| gl.stencilFunc(GL_EQUAL, i, 0xFF); |
| gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
| drawQuad(DEFAULT, m_colorProgram); |
| } |
| |
| gl.disable(GL_STENCIL_TEST); |
| dataColor.assign(dataColor.size(), 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]); |
| result &= verifyColorGradient(&dataColor[0], function, COLOR_CHECK_STENCIL, TEX_SIZE, TEX_SIZE); |
| } |
| } |
| |
| // clean up |
| restoreDrawReadBuffer(); |
| gl.deleteFramebuffers(1, &fbo); |
| gl.deleteTextures(1, &texColor); |
| |
| return result; |
| } |
| |
| class InitialStateTest : public deqp::TestCase |
| { |
| public: |
| InitialStateTest(deqp::Context& context); |
| virtual ~InitialStateTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| InitialStateTest::InitialStateTest(deqp::Context& context) |
| : deqp::TestCase(context, "initial_state", "TEXTURE_STENCIL_SIZE for the default texture objects should be 0") |
| { |
| } |
| |
| InitialStateTest::~InitialStateTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult InitialStateTest::iterate(void) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| for (int i = 0; i < DE_LENGTH_OF_ARRAY(coreTexTargets); i++) |
| { |
| GLenum target = coreTexTargets[i]; |
| |
| GLfloat fp; |
| gl.getTexLevelParameterfv(target, 0, GL_TEXTURE_STENCIL_SIZE, &fp); |
| if (deFloatCmpNE(fp, 0.0f)) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "gl.getTexLevelParameterfv: Parameter is not 0" |
| << tcu::TestLog::EndMessage; |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| |
| GLint ip; |
| gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_STENCIL_SIZE, &ip); |
| if (deFloatCmpNE((float)ip, 0.0f)) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "gl.getTexLevelParameteriv: Parameter is not 0" |
| << tcu::TestLog::EndMessage; |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| class ValidateErrorsTest : public BaseTest |
| { |
| public: |
| ValidateErrorsTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~ValidateErrorsTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| protected: |
| bool checkErrors(); |
| }; |
| |
| ValidateErrorsTest::ValidateErrorsTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| ValidateErrorsTest::~ValidateErrorsTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult ValidateErrorsTest::iterate(void) |
| { |
| createTextures(); |
| if (checkErrors()) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| destroyTextures(); |
| return STOP; |
| } |
| |
| // Error tests [desktop only]: |
| |
| // - The error INVALID_ENUM is generated if ReadPixels is |
| // called where format is DEPTH_STENCIL and type is not |
| // UNSIGNED_INT_24_8, or FLOAT_32_UNSIGNED_INT_24_8_REV. |
| |
| // - The error INVALID_OPERATION is generated if ReadPixels |
| // is called where type is UNSIGNED_INT_24_8 or |
| // FLOAT_32_UNSIGNED_INT_24_8_REV and format is not DEPTH_STENCIL. |
| |
| // - The error INVALID_OPERATION is generated if ReadPixels |
| // is called where format is DEPTH_STENCIL and there is not both a |
| // depth buffer and a stencil buffer. |
| |
| // - Calling GetTexImage with a <format> of DEPTH_COMPONENT when the |
| // base internal format of the texture image is not DEPTH_COMPONENT |
| // or DEPTH_STENCIL causes the error INVALID_OPERATION. |
| |
| // - Calling GetTexImage with a <format> of DEPTH_STENCIL when |
| // the base internal format of the texture image is not |
| // DEPTH_STENCIL causes the error INVALID_OPERATION. |
| |
| // Error tests [Halti only]: |
| |
| // - The error INVALID_ENUM is generated if ReadPixels is |
| // called where format is DEPTH_STENCIL. |
| |
| // Error tests [desktop and Halti]: |
| |
| // - TexImage generates INVALID_OPERATION if one of the base internal format |
| // and format is DEPTH_COMPONENT or DEPTH_STENCIL, and the other is neither |
| // of these values. |
| |
| // - The error INVALID_OPERATION is generated if CopyTexImage |
| // is called where format is DEPTH_STENCIL and there is not both a |
| // depth buffer and a stencil buffer. |
| bool ValidateErrorsTest::checkErrors() |
| { |
| bool result = true; |
| GLuint fbo, fbo2; |
| GLuint texColor; |
| std::vector<GLfloat> data(4 * TEX_SIZE * TEX_SIZE, 0.0f); |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| const glw::Functions& gl = renderContext.getFunctions(); |
| bool isContextES = glu::isContextTypeES(renderContext.getType()); |
| |
| if (isContextES) |
| { |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]); |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]); |
| |
| GLenum error = gl.getError(); |
| if (((GL_INVALID_OPERATION != error) && (GL_INVALID_ENUM != error)) && |
| !((GL_NO_ERROR == error) && m_context.getContextInfo().isExtensionSupported("GL_NV_read_depth_stencil"))) |
| { |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]); |
| if (gl.getError() != GL_INVALID_OPERATION) |
| result = false; |
| } |
| |
| restoreDrawReadBuffer(); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| } |
| else |
| { |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]); |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| for (unsigned int i = 0; i < m_nonDepthStencilTypesCount; i++) |
| { |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_nonDepthStencilTypes[i], &data[0]); |
| if (gl.getError() != GL_INVALID_ENUM) |
| result = false; |
| } |
| |
| for (unsigned int i = 0; i < m_nonDepthStencilFormatsCount; i++) |
| { |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, m_nonDepthStencilFormats[i], m_typeFormat.type, &data[0]); |
| |
| if (gl.getError() != GL_INVALID_OPERATION) |
| result = false; |
| } |
| |
| for (int i = 0; i < 2; i++) |
| { |
| // setup texture/fbo |
| gl.genTextures(1, &texColor); |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| GLenum attachmentType = (i == 0) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT; |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, attachmentType, GL_TEXTURE_2D, m_textures[packedTexImage], 0); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texColor); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0); |
| |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]); |
| if (gl.getError() != GL_INVALID_OPERATION) |
| result = false; |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.deleteFramebuffers(1, &fbo); |
| gl.deleteTextures(1, &texColor); |
| } |
| |
| for (unsigned int i = 0; i < m_otherBaseFormatsCount; i++) |
| { |
| GLenum format = m_otherBaseFormats[i]; |
| gl.genTextures(1, &texColor); |
| gl.bindTexture(GL_TEXTURE_2D, texColor); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, format, TEX_SIZE, TEX_SIZE, 0, format, GL_UNSIGNED_BYTE, 0); |
| |
| if (format != GL_DEPTH_COMPONENT) |
| { |
| gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, &data[0]); |
| |
| if (gl.getError() != GL_INVALID_OPERATION) |
| result = false; |
| } |
| |
| gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, &data[0]); |
| if (gl.getError() != GL_INVALID_OPERATION) |
| result = false; |
| |
| gl.deleteTextures(1, &texColor); |
| } |
| } |
| |
| bool coreGL = !glu::isContextTypeES(m_context.getRenderContext().getType()); |
| for (int i = 0; i < 4; i++) |
| { |
| int limit; |
| if (i < 2) |
| limit = m_nonDepthStencilFormatsCount; |
| else |
| limit = m_otherBaseFormatsCount; |
| |
| for (int j = 0; j < limit; j++) |
| { |
| GLint internalFormat = 0; |
| GLint format = 0; |
| |
| gl.genTextures(1, &texColor); |
| gl.bindTexture(GL_TEXTURE_2D, texColor); |
| setupTexture(); |
| |
| switch (i) |
| { |
| case 0: |
| internalFormat = GL_DEPTH_COMPONENT; |
| format = m_nonDepthStencilFormats[j]; |
| break; |
| case 1: |
| internalFormat = GL_DEPTH_STENCIL; |
| format = m_nonDepthStencilFormats[j]; |
| break; |
| case 2: |
| internalFormat = m_otherBaseFormats[j]; |
| format = GL_DEPTH_COMPONENT; |
| break; |
| case 3: |
| internalFormat = m_otherBaseFormats[j]; |
| format = GL_DEPTH_STENCIL; |
| break; |
| } |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, TEX_SIZE, TEX_SIZE, 0, format, |
| (format == GL_DEPTH_STENCIL) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_BYTE, 0); |
| |
| GLenum expectedError = GL_INVALID_OPERATION; |
| if (coreGL && (format == GL_STENCIL_INDEX)) |
| { |
| // The OpenGL 4.3 spec is imprecise about what error this should generate |
| // see Bugzilla 10134: TexImage with a <format> of STENCIL_INDEX |
| // 4.3 core (Feb 14 2013) p. 174: |
| // (describing TexImage3D) |
| // The format STENCIL_INDEX is not allowed. |
| // The new OpenGL 4.4 feature ARB_texture_stencil8 removes this error. So |
| // the best we can do for OpenGL is to just allow any error, or no error, |
| // for this specific case. |
| gl.getError(); |
| } |
| else if (gl.getError() != expectedError) |
| result = false; |
| |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.deleteTextures(1, &texColor); |
| } |
| } |
| |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0); |
| |
| gl.genFramebuffers(1, &fbo2); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo2); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0); |
| |
| GLuint tex; |
| gl.genTextures(1, &tex); |
| gl.bindTexture(GL_TEXTURE_2D, tex); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, 0); |
| |
| for (int i = 0; i < 2; i++) |
| { |
| switch (i) |
| { |
| case 0: |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| gl.bindTexture(GL_TEXTURE_2D, tex); |
| break; |
| case 1: |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo2); |
| gl.bindTexture(GL_TEXTURE_2D, tex); |
| break; |
| } |
| |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 0, 0, TEX_SIZE, TEX_SIZE, 0); |
| |
| GLenum error = gl.getError(); |
| if ((GL_INVALID_OPERATION != error) && (GL_INVALID_ENUM != error)) |
| { |
| gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 0, 0, TEX_SIZE, TEX_SIZE, 0); |
| if (gl.getError() != GL_INVALID_OPERATION) |
| result = false; |
| } |
| |
| restoreDrawReadBuffer(); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| } |
| |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.deleteTextures(1, &tex); |
| |
| gl.deleteFramebuffers(1, &fbo); |
| gl.deleteFramebuffers(1, &fbo2); |
| |
| return result; |
| } |
| |
| class VerifyReadPixelsTest : public BaseTest |
| { |
| public: |
| VerifyReadPixelsTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~VerifyReadPixelsTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| VerifyReadPixelsTest::VerifyReadPixelsTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| VerifyReadPixelsTest::~VerifyReadPixelsTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult VerifyReadPixelsTest::iterate(void) |
| { |
| // Use readpixels to verify the results for the 5 textures above are correct. |
| // Note that in ES you can only use gl.readpixels on color buffers. |
| // Test method: |
| // - on desktop: ReadPixel DEPTH_STENCIL value to buffer. Verify gradient. |
| // - on desktop/Halti: Create FBO with color/depth/stencil attachment. |
| // Draw a quad with depth texture bound. Verify gradient. |
| // Draw 256 times using stencil test and gradient color. Verify gradient. |
| |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| const glw::Functions& gl = renderContext.getFunctions(); |
| std::size_t dataSize = static_cast<std::size_t>(TEX_SIZE * TEX_SIZE * m_typeFormat.size); |
| std::vector<GLubyte> data(dataSize); |
| |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| for (int i = 0; i < NUM_TEXTURES; i++) |
| { |
| // Read DEPTH_STENCIL value, applies only to desktop |
| if (!glu::isContextTypeES(renderContext.getType())) |
| { |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[i]); |
| |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| data.assign(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]); |
| result &= verifyDepthStencilGradient(&data[0], i, TEX_SIZE, TEX_SIZE); |
| |
| restoreDrawReadBuffer(); |
| } |
| |
| // On ES3.2 we have to render to color buffer to verify. |
| // We can run this also on desktop. |
| result &= doReadPixels(m_textures[i], i); |
| } |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class VerifyGetTexImageTest : public BaseTest |
| { |
| public: |
| VerifyGetTexImageTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~VerifyGetTexImageTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| VerifyGetTexImageTest::VerifyGetTexImageTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| VerifyGetTexImageTest::~VerifyGetTexImageTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult VerifyGetTexImageTest::iterate(void) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| std::vector<GLubyte> data(TEX_SIZE * TEX_SIZE * m_typeFormat.size); |
| |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| for (int i = 0; i < NUM_TEXTURES; i++) |
| { |
| data.assign(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0); |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[i]); |
| gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]); |
| result &= verifyDepthStencilGradient(&data[0], i, TEX_SIZE, TEX_SIZE); |
| } |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class VerifyCopyTexImageTest : public BaseTest |
| { |
| public: |
| VerifyCopyTexImageTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~VerifyCopyTexImageTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| VerifyCopyTexImageTest::VerifyCopyTexImageTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| VerifyCopyTexImageTest::~VerifyCopyTexImageTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult VerifyCopyTexImageTest::iterate(void) |
| { |
| // After rendering to depth and stencil, CopyTexImage the results to a new |
| // DEPTH_STENCIL texture. Attach this texture to a new FBO. Verify that |
| // depth and stencil tests work with the copied data. |
| |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| // setup shader |
| GLint uColor; |
| setupColorProgram(uColor); |
| |
| // setup and copy texture/fbo |
| GLuint tex; |
| gl.genTextures(1, &tex); |
| GLuint fbo; |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]); |
| gl.bindTexture(GL_TEXTURE_2D, tex); |
| setupTexture(); |
| |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, |
| NULL); |
| gl.copyTexImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, 0, 0, TEX_SIZE, TEX_SIZE, 0); |
| |
| restoreDrawReadBuffer(); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0); |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| int status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status |
| << tcu::TestLog::EndMessage; |
| result = false; |
| restoreDrawReadBuffer(); |
| } |
| else |
| { |
| // render |
| gl.enable(GL_DEPTH_TEST); |
| gl.depthFunc(GL_LEQUAL); |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| gl.enable(GL_STENCIL_TEST); |
| gl.stencilFunc(GL_EQUAL, 0x1, 0xFF); |
| gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
| drawQuad(DEFAULT, m_colorProgram); |
| gl.disable(GL_STENCIL_TEST); |
| |
| // verify |
| std::vector<GLubyte> data(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0); |
| gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]); |
| result &= verifyDepthStencilGradient(&data[0], verifyCopyTexImage, TEX_SIZE, TEX_SIZE); |
| |
| restoreDrawReadBuffer(); |
| |
| result &= doReadPixels(tex, verifyCopyTexImage); |
| } |
| |
| // clean up |
| gl.deleteFramebuffers(1, &fbo); |
| gl.deleteTextures(1, &tex); |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class VerifyPartialAttachmentsTest : public BaseTest |
| { |
| public: |
| VerifyPartialAttachmentsTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~VerifyPartialAttachmentsTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| VerifyPartialAttachmentsTest::VerifyPartialAttachmentsTest(deqp::Context& context, const TypeFormat& tf) |
| : BaseTest(context, tf) |
| { |
| } |
| |
| VerifyPartialAttachmentsTest::~VerifyPartialAttachmentsTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult VerifyPartialAttachmentsTest::iterate(void) |
| { |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| |
| // - Create an FBO with a packed depth stencil renderbuffer attached to |
| // DEPTH_ATTACHMENT only. If this FBO is complete, stencil test must act as |
| // if there is no stencil buffer (always pass.) |
| |
| // - Create an FBO with a packed depth stencil renderbuffer attached to |
| // STENCIL_ATTACHMENT only. If this FBO is complete, depth test must act as |
| // if there is no depth buffer (always pass.) |
| |
| // - Create an FBO with a packed depth stencil renderbuffer attached to |
| // STENCIL_ATTACHMENT only. If this FBO is complete, occlusion query must |
| // act as if there is no depth buffer (always pass.) |
| |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| const glw::Functions& gl = renderContext.getFunctions(); |
| bool isContextES = glu::isContextTypeES(renderContext.getType()); |
| |
| // setup shader |
| GLint uColor; |
| setupColorProgram(uColor); |
| |
| GLuint occ; |
| gl.genQueries(1, &occ); |
| |
| for (int i = 0; i < 3; i++) |
| { |
| // setup fbo |
| GLuint fbo; |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| GLuint rbo[2]; // color, D/S |
| gl.genRenderbuffers(2, rbo); |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]); |
| gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, TEX_SIZE, TEX_SIZE); |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]); |
| gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE); |
| |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]); |
| setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0); |
| |
| switch (i) |
| { |
| case 0: |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); |
| break; |
| case 1: |
| case 2: |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); |
| break; |
| default: |
| result = false; |
| } |
| |
| if (!result) |
| break; |
| |
| int status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| else |
| { |
| // render |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| if (isContextES) |
| gl.clearDepthf(1.0f); |
| else |
| gl.clearDepth(1.0); |
| |
| gl.clearStencil(0); |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| |
| switch (i) |
| { |
| case 0: |
| gl.disable(GL_DEPTH_TEST); |
| gl.enable(GL_STENCIL_TEST); |
| gl.stencilFunc(GL_NEVER, 0xFF, 0xFF); |
| gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
| break; |
| case 1: |
| gl.enable(GL_DEPTH_TEST); |
| gl.depthFunc(GL_NEVER); |
| gl.disable(GL_STENCIL_TEST); |
| break; |
| case 2: |
| gl.enable(GL_DEPTH_TEST); |
| gl.depthFunc(GL_NEVER); |
| gl.disable(GL_STENCIL_TEST); |
| gl.beginQuery(GL_ANY_SAMPLES_PASSED, occ); |
| break; |
| default: |
| break; |
| } |
| |
| drawQuad(DEFAULT, m_colorProgram); |
| |
| if (i == 2) |
| { |
| GLuint n; |
| |
| gl.endQuery(GL_ANY_SAMPLES_PASSED); |
| gl.getQueryObjectuiv(occ, GL_QUERY_RESULT, &n); |
| |
| if (n > 0) |
| { |
| drawQuad(DEFAULT, m_colorProgram); |
| } |
| } |
| |
| std::vector<GLuint> data(TEX_SIZE * TEX_SIZE, 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); |
| result &= verifyColorGradient(&data[0], verifyPartialAttachments, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE); |
| } |
| |
| restoreDrawReadBuffer(); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| |
| // clean up |
| gl.deleteFramebuffers(1, &fbo); |
| gl.deleteRenderbuffers(2, rbo); |
| } |
| |
| gl.deleteQueries(1, &occ); |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class VerifyMixedAttachmentsTest : public BaseTest |
| { |
| public: |
| VerifyMixedAttachmentsTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~VerifyMixedAttachmentsTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| VerifyMixedAttachmentsTest::VerifyMixedAttachmentsTest(deqp::Context& context, const TypeFormat& tf) |
| : BaseTest(context, tf) |
| { |
| } |
| |
| VerifyMixedAttachmentsTest::~VerifyMixedAttachmentsTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult VerifyMixedAttachmentsTest::iterate(void) |
| { |
| // Create FBOs that mix DEPTH_STENCIL renderbuffers with DEPTH or STENCIL |
| // renderbuffers. If these FBOs are complete, depth and stencil test |
| // must work properly. |
| |
| // Create an FBO with two different packed depth stencil renderbuffers, one |
| // attached to DEPTH_ATTACHMENT and the other attached to STENCIL_ATTACHMENT. |
| // Querying DEPTH_STENCIL_ATTACHMENT must fail with INVALID_OPERATION. If |
| // this FBO is complete, depth and stencil tests must work properly. |
| |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| const glw::Functions& gl = renderContext.getFunctions(); |
| bool isContextES = glu::isContextTypeES(renderContext.getType()); |
| |
| GLint uColor; |
| setupColorProgram(uColor); |
| |
| for (int i = 0; i < 3; i++) |
| { |
| // set up FBO/RBOs |
| GLuint fbo; |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| GLuint rbo[3]; // color, DEPTH_STENCIL, DEPTH/STENCIL |
| gl.genRenderbuffers(3, rbo); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]); |
| gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]); |
| gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[2]); |
| switch (i) |
| { |
| case 0: |
| gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[2]); |
| break; |
| case 1: |
| gl.renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[2]); |
| break; |
| case 2: |
| gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[2]); |
| |
| GLint param; |
| gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
| GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, ¶m); |
| if (gl.getError() != GL_INVALID_OPERATION) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message |
| << "Expected INVALID_OPERATION for DEPTH_STENCIL_ATTACHMENT query" |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| |
| break; |
| } |
| |
| GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) |
| { |
| if (status == GL_FRAMEBUFFER_UNSUPPORTED) |
| { |
| /* The spec only requires |
| |
| "when both depth and stencil attachments are present, implementations are only |
| required to support framebuffer objects where both attachments refer to the same image." |
| |
| Thus, it is accepatable for an implementation returning GL_FRAMEBUFFER_UNSUPPORTED. And the |
| test can NOT be marked as fail. |
| */ |
| } |
| else |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete" << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| } |
| else |
| { |
| |
| // render |
| // step 1 |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| gl.enable(GL_DEPTH_TEST); |
| gl.depthFunc(GL_LEQUAL); |
| |
| if (isContextES) |
| gl.clearDepthf(1.0f); |
| else |
| gl.clearDepth(1.0); |
| |
| gl.enable(GL_STENCIL_TEST); |
| gl.stencilFunc(GL_ALWAYS, 0x1, 0xFF); |
| gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); |
| gl.clearStencil(0); |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| drawQuad(DEPTH_SPAN1, m_colorProgram); |
| |
| // step 2 |
| gl.stencilFunc(GL_EQUAL, 0x1, 0xFF); |
| gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| drawQuad(DEFAULT, m_colorProgram); |
| |
| std::vector<GLuint> data(TEX_SIZE * TEX_SIZE, 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); |
| result &= verifyColorGradient(&data[0], verifyMixedAttachments, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE); |
| } |
| |
| // clean up |
| gl.deleteRenderbuffers(3, rbo); |
| gl.deleteFramebuffers(1, &fbo); |
| } |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class VerifyParametersTest : public BaseTest |
| { |
| public: |
| VerifyParametersTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~VerifyParametersTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| VerifyParametersTest::VerifyParametersTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| VerifyParametersTest::~VerifyParametersTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult VerifyParametersTest::iterate(void) |
| { |
| // Verify GetFramebufferAttachmentParameter queries of each <pname> on |
| // DEPTH_STENCIL_ATTACHMENT work correctly if both attachments are populated |
| // with the same object. |
| |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]); |
| |
| GLint param; |
| gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
| GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, ¶m); |
| if (param != GL_TEXTURE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message |
| << "Invalid value for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: " << param |
| << tcu::TestLog::EndMessage; |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| return STOP; |
| } |
| |
| const AttachmentParam* attachmentParams = getAttachmentParams(); |
| for (GLuint i = 0; i < m_attachmentParamsCount; i++) |
| { |
| int ref; |
| GLenum pname = attachmentParams[i].pname; |
| if (GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE == pname) |
| { |
| gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, pname, ¶m); |
| if (gl.getError() != GL_INVALID_OPERATION) |
| result = false; |
| continue; |
| } |
| |
| gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, pname, ¶m); |
| |
| ref = attachmentParams[i].value; |
| if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) |
| ref = m_textures[packedTexImage]; |
| |
| if (param != ref) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for pname " << attachmentParams[i].pname |
| << ": " << param << " ( expected " << ref << ")" << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| } |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class RenderbuffersTest : public BaseTest |
| { |
| public: |
| RenderbuffersTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~RenderbuffersTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| RenderbuffersTest::RenderbuffersTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| RenderbuffersTest::~RenderbuffersTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult RenderbuffersTest::iterate(void) |
| { |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| |
| // Verify RENDERBUFFER_DEPTH_SIZE and RENDERBUFFER_STENCIL_SIZE report |
| // appropriate values for for DEPTH_STENCIL renderbuffers. |
| |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]); |
| |
| GLuint rbo; |
| gl.genRenderbuffers(1, &rbo); |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo); |
| gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); |
| |
| GLint param; |
| gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_DEPTH_SIZE, ¶m); |
| if (param != m_typeFormat.d) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Invalid depth: " << param << ", expected: " << m_typeFormat.d |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| |
| gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STENCIL_SIZE, ¶m); |
| if (param != m_typeFormat.s) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Invalid stencil: " << param << ", expected: " << m_typeFormat.s |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, 0); |
| gl.deleteRenderbuffers(1, &rbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class StencilSizeTest : public BaseTest |
| { |
| public: |
| StencilSizeTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~StencilSizeTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| StencilSizeTest::StencilSizeTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| StencilSizeTest::~StencilSizeTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult StencilSizeTest::iterate(void) |
| { |
| // [desktop only] Verify TEXTURE_STENCIL_SIZE reports 8 for DEPTH_STENCIL |
| // textures, and 0 for RGBA and DEPTH_COMPONENT textures. |
| |
| createTextures(); |
| renderToTextures(); |
| |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| bool result = true; |
| GLint param; |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]); |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, ¶m); |
| if (param != 8) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for DEPTH_STENCIL stencil size: " << param |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| |
| GLuint texRGBA; |
| gl.genTextures(1, &texRGBA); |
| gl.bindTexture(GL_TEXTURE_2D, texRGBA); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, ¶m); |
| if (param != 0) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for RGBA stencil size: " << param |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| gl.deleteTextures(1, &texRGBA); |
| |
| GLuint texDepth; |
| gl.genTextures(1, &texDepth); |
| gl.bindTexture(GL_TEXTURE_2D, texDepth); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, |
| 0); |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, ¶m); |
| if (param != 0) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for DEPTH_COMPONENT stencil size: " << param |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| gl.deleteTextures(1, &texDepth); |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class ClearBufferTest : public BaseTest |
| { |
| public: |
| ClearBufferTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~ClearBufferTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| ClearBufferTest::ClearBufferTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| ClearBufferTest::~ClearBufferTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult ClearBufferTest::iterate(void) |
| { |
| // Verify ClearBufferfv correctly clears the depth channel of a DEPTH_STENCIL |
| // FBO attachment (and does not touch the stencil channel.) |
| // Verify ClearBufferiv correctly clears the stencil channel of a |
| // DEPTH_STENCIL FBO attachment (and does not touch the depth channel.) |
| // Verify ClearBufferfi correctly clears the depth and stencil channels of a |
| // DEPTH_STENCIL FBO attachment. |
| |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| GLfloat valuef; |
| GLint valuei; |
| GLenum status; |
| |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| // setup shader |
| GLint uColor; |
| setupColorProgram(uColor); |
| |
| for (int i = 0; i < 3; i++) |
| { |
| // setup texture/fbo |
| GLuint tex; |
| GLuint texColor; |
| GLuint fbo; |
| gl.genTextures(1, &tex); |
| gl.genTextures(1, &texColor); |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| gl.bindTexture(GL_TEXTURE_2D, tex); |
| setupTexture(); |
| std::vector<GLbyte> data; |
| createGradient(data); |
| gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, |
| &data[0]); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texColor); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0); |
| |
| setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0); |
| |
| status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| else |
| { |
| // clear relevant buffers |
| switch (i) |
| { |
| case 0: |
| valuef = 1.0f; |
| gl.clearBufferfv(GL_DEPTH, 0, &valuef); |
| break; |
| case 1: |
| valuei = 0xff; |
| gl.clearBufferiv(GL_STENCIL, 0, &valuei); |
| break; |
| case 2: |
| valuef = 1.0f; |
| valuei = 0xff; |
| gl.clearBufferfi(GL_DEPTH_STENCIL, 0, valuef, valuei); |
| break; |
| } |
| |
| // render reference image |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| gl.enable(GL_DEPTH_TEST); |
| gl.depthFunc(GL_LEQUAL); |
| gl.enable(GL_STENCIL_TEST); |
| gl.stencilFunc(GL_EQUAL, 0xFF, 0xFF); |
| gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| drawQuad(DEFAULT, m_colorProgram); |
| |
| // verify |
| std::vector<GLubyte> readData(TEX_SIZE * TEX_SIZE * 4, 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &readData[0]); |
| result &= |
| verifyColorGradient(&readData[0], verifyClearBufferDepth + i, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE); |
| } |
| |
| // destroy texture/fbo |
| restoreDrawReadBuffer(); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.deleteFramebuffers(1, &fbo); |
| gl.deleteTextures(1, &tex); |
| gl.deleteTextures(1, &texColor); |
| } |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class BlitTest : public BaseTest |
| { |
| public: |
| BlitTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~BlitTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| BlitTest::BlitTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| BlitTest::~BlitTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult BlitTest::iterate(void) |
| { |
| // Verify that NEAREST filtered blits of DEPTH and/or STENCIL between two |
| // FBOs with the same format packed depth stencil attachment work. Test |
| // non-multisample [1->1], multisample resolve [N->1], and multisample |
| // replicate [1->N] blits, for each supported value of N up to MAX_SAMPLES. |
| |
| createTextures(); |
| renderToTextures(); |
| |
| GLuint fbo[3]; // Framebuffers: source, dest, downsample |
| GLuint rbo[4]; // Renderbuffers: source D/S, dest D/S, dest color, downsample color |
| GLint maxSamples; |
| int srcSamples, destSamples; |
| bool result = true; |
| |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| const glw::Functions& gl = renderContext.getFunctions(); |
| bool isContextES = glu::isContextTypeES(renderContext.getType()); |
| |
| std::vector<GLuint> data(TEX_SIZE * TEX_SIZE); |
| |
| GLint uColor; |
| setupColorProgram(uColor); |
| |
| gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples); |
| |
| // ES does not allow SAMPLE_BUFFERS for the draw frame |
| // buffer is greater than zero when doing a blit. |
| int loopCount = isContextES ? 1 : 2; |
| |
| for (int j = 0; j < loopCount; j++) |
| { |
| for (int i = 0; i <= maxSamples; i++) |
| { |
| // Create FBO/RBO |
| gl.genFramebuffers(3, fbo); |
| gl.genRenderbuffers(4, rbo); |
| |
| if (j == 0) |
| { |
| srcSamples = i; |
| destSamples = 0; |
| } |
| else |
| { |
| srcSamples = 0; |
| destSamples = i; |
| } |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[0]); |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]); |
| gl.renderbufferStorageMultisample(GL_RENDERBUFFER, srcSamples, m_typeFormat.format, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[0]); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[1]); |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]); |
| gl.renderbufferStorageMultisample(GL_RENDERBUFFER, destSamples, m_typeFormat.format, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[2]); |
| gl.renderbufferStorageMultisample(GL_RENDERBUFFER, destSamples, GL_RGBA8, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[2]); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[2]); |
| gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[3]); |
| gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE); |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[3]); |
| |
| // Render |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[0]); |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| gl.enable(GL_DEPTH_TEST); |
| gl.depthFunc(GL_LEQUAL); |
| |
| if (isContextES) |
| gl.clearDepthf(1.0f); |
| else |
| gl.clearDepth(1.0); |
| |
| gl.enable(GL_STENCIL_TEST); |
| gl.stencilFunc(GL_ALWAYS, 0x1, 0xFF); |
| gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); |
| gl.clearStencil(0); |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| drawQuad(DEPTH_SPAN1, m_colorProgram); |
| |
| restoreDrawReadBuffer(); |
| |
| // Blit |
| gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[0]); |
| gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]); |
| setDrawReadBuffer(GL_NONE, GL_NONE); |
| gl.blitFramebuffer(0, 0, TEX_SIZE, TEX_SIZE, 0, 0, TEX_SIZE, TEX_SIZE, |
| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); |
| restoreDrawReadBuffer(); |
| |
| // Verify |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[1]); |
| setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0); |
| |
| gl.stencilFunc(GL_EQUAL, 0x1, 0xFF); |
| gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| drawQuad(DEFAULT, m_colorProgram); |
| |
| restoreDrawReadBuffer(); |
| |
| // Downsample blit |
| gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]); |
| gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[2]); |
| setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0); |
| gl.blitFramebuffer(0, 0, TEX_SIZE, TEX_SIZE, 0, 0, TEX_SIZE, TEX_SIZE, GL_COLOR_BUFFER_BIT, GL_NEAREST); |
| restoreDrawReadBuffer(); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[2]); |
| |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); |
| |
| result &= verifyColorGradient(&data[0], verifyBlit, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE); |
| |
| // Clean up |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO); |
| gl.bindRenderbuffer(GL_RENDERBUFFER, 0); |
| |
| gl.deleteRenderbuffers(4, rbo); |
| gl.deleteFramebuffers(3, fbo); |
| } |
| } |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| class StencilTexturingTest : public BaseTest |
| { |
| public: |
| StencilTexturingTest(deqp::Context& context, const TypeFormat& tf); |
| virtual ~StencilTexturingTest(); |
| |
| virtual tcu::TestNode::IterateResult iterate(void); |
| }; |
| |
| StencilTexturingTest::StencilTexturingTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf) |
| { |
| } |
| |
| StencilTexturingTest::~StencilTexturingTest() |
| { |
| } |
| |
| tcu::TestNode::IterateResult StencilTexturingTest::iterate(void) |
| { |
| // Verifies that either depth or stencil can be sampled depending on |
| // GL_DEPTH_STENCIL_TEXTURE_MODE |
| |
| const glu::RenderContext& renderContext = m_context.getRenderContext(); |
| glu::ContextType contextType = renderContext.getType(); |
| const glw::Functions& gl = renderContext.getFunctions(); |
| |
| bool notSupported = false; |
| if (glu::isContextTypeES(contextType)) |
| notSupported = !glu::contextSupports(contextType, glu::ApiType::es(3, 1)); |
| else |
| notSupported = !glu::contextSupports(contextType, glu::ApiType::core(4, 3)); |
| |
| if (notSupported) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "stencil_texturing extension is not supported"); |
| return STOP; |
| } |
| |
| createTextures(); |
| renderToTextures(); |
| |
| bool result = true; |
| GLuint fbo; |
| gl.genFramebuffers(1, &fbo); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| GLuint texColor; |
| gl.genTextures(1, &texColor); |
| gl.bindTexture(GL_TEXTURE_2D, texColor); |
| setupTexture(); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0); |
| setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0); |
| |
| // Step 1: Verify depth values |
| GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); |
| if (status != GL_FRAMEBUFFER_COMPLETE) |
| { |
| m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status |
| << tcu::TestLog::EndMessage; |
| result = false; |
| } |
| else |
| { |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]); |
| |
| gl.disable(GL_DEPTH_TEST); |
| gl.depthMask(GL_FALSE); |
| gl.disable(GL_STENCIL_TEST); |
| gl.viewport(0, 0, TEX_SIZE, TEX_SIZE); |
| gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f); |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); |
| setupTextureProgram(); |
| drawQuad(DEFAULT, m_textureProgram); |
| |
| std::vector<GLuint> dataColor(TEX_SIZE * TEX_SIZE, 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]); |
| result &= verifyColorGradient(&dataColor[0], packedTexImage, COLOR_CHECK_DEPTH, TEX_SIZE, TEX_SIZE); |
| |
| // Step 2: Verify stencil values |
| gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); |
| setupStencilProgram(); |
| drawQuad(DEFAULT, m_stencilProgram); |
| |
| dataColor.assign(TEX_SIZE * TEX_SIZE, 0); |
| gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]); |
| result &= verifyColorGradient(&dataColor[0], packedTexImage, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE); |
| } |
| |
| restoreDrawReadBuffer(); |
| gl.deleteFramebuffers(1, &fbo); |
| gl.deleteTextures(1, &texColor); |
| |
| destroyTextures(); |
| if (result) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| PackedDepthStencilTests::PackedDepthStencilTests(deqp::Context& context) |
| : TestCaseGroup(context, "packed_depth_stencil", "") |
| { |
| } |
| |
| PackedDepthStencilTests::~PackedDepthStencilTests(void) |
| { |
| } |
| |
| void PackedDepthStencilTests::init(void) |
| { |
| TestCaseGroup* validateErrorsGroup = new deqp::TestCaseGroup(m_context, "validate_errors", ""); |
| TestCaseGroup* verifyReadPixelsGroup = new deqp::TestCaseGroup(m_context, "verify_read_pixels", ""); |
| TestCaseGroup* verifyGetTexImageGroup = new deqp::TestCaseGroup(m_context, "verify_get_tex_image", ""); |
| TestCaseGroup* verifyCopyTexImageGroup = new deqp::TestCaseGroup(m_context, "verify_copy_tex_image", ""); |
| TestCaseGroup* verifyPartialAttachmentsGroup = new deqp::TestCaseGroup(m_context, "verify_partial_attachments", ""); |
| TestCaseGroup* verifyMixedAttachmentsGroup = new deqp::TestCaseGroup(m_context, "verify_mixed_attachments", ""); |
| TestCaseGroup* verifyParametersGroup = new deqp::TestCaseGroup(m_context, "verify_parameters", ""); |
| TestCaseGroup* renderbuffersGroup = new deqp::TestCaseGroup(m_context, "renderbuffers", ""); |
| TestCaseGroup* clearBufferGroup = new deqp::TestCaseGroup(m_context, "clear_buffer", ""); |
| TestCaseGroup* blitGroup = new deqp::TestCaseGroup(m_context, "blit", ""); |
| TestCaseGroup* stencilTexturingGroup = new deqp::TestCaseGroup(m_context, "stencil_texturing", ""); |
| TestCaseGroup* stencilSizeGroup = new deqp::TestCaseGroup(m_context, "stencil_size", ""); |
| |
| bool isContextCoreGL = !glu::isContextTypeES(m_context.getRenderContext().getType()); |
| if (isContextCoreGL) |
| validateErrorsGroup->addChild(new InitialStateTest(m_context)); |
| |
| for (int i = 0; i < NUM_TEXTURE_TYPES; i++) |
| { |
| const TypeFormat& typeFormat = TextureTypes[i]; |
| validateErrorsGroup->addChild(new ValidateErrorsTest(m_context, typeFormat)); |
| verifyReadPixelsGroup->addChild(new VerifyReadPixelsTest(m_context, typeFormat)); |
| verifyPartialAttachmentsGroup->addChild(new VerifyPartialAttachmentsTest(m_context, typeFormat)); |
| verifyMixedAttachmentsGroup->addChild(new VerifyMixedAttachmentsTest(m_context, typeFormat)); |
| verifyParametersGroup->addChild(new VerifyParametersTest(m_context, typeFormat)); |
| renderbuffersGroup->addChild(new RenderbuffersTest(m_context, typeFormat)); |
| clearBufferGroup->addChild(new ClearBufferTest(m_context, typeFormat)); |
| blitGroup->addChild(new BlitTest(m_context, typeFormat)); |
| stencilTexturingGroup->addChild(new StencilTexturingTest(m_context, typeFormat)); |
| |
| if (isContextCoreGL) |
| { |
| verifyGetTexImageGroup->addChild(new VerifyGetTexImageTest(m_context, typeFormat)); |
| verifyCopyTexImageGroup->addChild(new VerifyCopyTexImageTest(m_context, typeFormat)); |
| stencilSizeGroup->addChild(new StencilSizeTest(m_context, typeFormat)); |
| } |
| } |
| |
| addChild(validateErrorsGroup); |
| addChild(verifyReadPixelsGroup); |
| addChild(verifyGetTexImageGroup); |
| addChild(verifyCopyTexImageGroup); |
| addChild(verifyPartialAttachmentsGroup); |
| addChild(verifyMixedAttachmentsGroup); |
| addChild(verifyParametersGroup); |
| addChild(renderbuffersGroup); |
| addChild(clearBufferGroup); |
| addChild(blitGroup); |
| addChild(stencilTexturingGroup); |
| addChild(stencilSizeGroup); |
| } |
| |
| } /* glcts namespace */ |