/** Verify rendered polygon anisotropy. * * @param gl OpenGL functions wrapper * * @return Returns points value. Less points means better anisotropy (smoother strips). */ GLuint TextureFilterAnisotropicDrawingTestCase::verifyScene(const glw::Functions& gl) { std::vector<GLubyte> pixels; pixels.resize(32 * 8 * 4); gl.readPixels(0, 23, 32, 8, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); GLuint sum = 0; GLubyte last = 0; GLubyte current = 0; for (int j = 0; j < 8; ++j) { for (int i = 0; i < 32; ++i) { current = pixels[(i + j * 32) * 4]; if (i > 0) sum += deAbs32((int)current - (int)last); last = current; } } return sum; }
static std::vector<std::string> getExtensions (const glw::Functions& gl, ApiType apiType) { using std::vector; using std::string; if (apiType.getProfile() == PROFILE_ES && apiType.getMajorVersion() == 2) { TCU_CHECK(gl.getString); const char* extStr = (const char*)gl.getString(GL_EXTENSIONS); GLU_EXPECT_NO_ERROR(gl.getError(), "glGetString(GL_EXTENSIONS)"); if (extStr) return de::splitString(extStr); else throw tcu::TestError("glGetString(GL_EXTENSIONS) returned null pointer", DE_NULL, __FILE__, __LINE__); } else { int numExtensions = 0; vector<string> extensions; TCU_CHECK(gl.getIntegerv && gl.getStringi); gl.getIntegerv(GL_NUM_EXTENSIONS, &numExtensions); GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_NUM_EXTENSIONS)"); if (numExtensions > 0) { extensions.resize(numExtensions); for (int ndx = 0; ndx < numExtensions; ndx++) { const char* const ext = (const char*)gl.getStringi(GL_EXTENSIONS, ndx); GLU_EXPECT_NO_ERROR(gl.getError(), "glGetStringi(GL_EXTENSIONS)"); if (ext) extensions[ndx] = ext; else throw tcu::TestError("glGetStringi(GL_EXTENSIONS) returned null pointer", DE_NULL, __FILE__, __LINE__); } } return extensions; } }
/** Verify if get* queries for GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT pname works as expected. * * @param gl OpenGL functions wrapper * * @return Returns true if queries test passed, false otherwise. */ bool TextureFilterAnisotropicQueriesTestCase::verifyGet(const glw::Functions& gl) { GLboolean bValue; GLint iValue; GLfloat fValue; GLdouble dValue; gl.getBooleanv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &bValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv"); gl.getIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &iValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv"); gl.getFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getFloatv"); if (glu::isContextTypeGLCore(m_context.getRenderContext().getType())) { gl.getDoublev(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublev"); } return true; }
static std::vector<int> querySampleCounts (const glw::Functions& gl, deUint32 format) { int numSampleCounts = 0; std::vector<int> sampleCounts; gl.getInternalformativ(GL_RENDERBUFFER, format, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts); if (numSampleCounts > 0) { sampleCounts.resize(numSampleCounts); gl.getInternalformativ(GL_RENDERBUFFER, format, GL_SAMPLES, (glw::GLsizei)sampleCounts.size(), &sampleCounts[0]); } GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query sample counts for format"); return sampleCounts; }
/** Generate texture and set filtering parameters. * * @param gl OpenGL functions wrapper * @param target Texture target * @param internalFormat Texture internal format */ void TextureFilterAnisotropicDrawingTestCase::generateTexture(const glw::Functions& gl, GLenum target) { gl.genTextures(1, &m_texture); GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures"); gl.bindTexture(target, m_texture); GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture"); gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); gl.texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); gl.texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 1); GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); }
/** Render polygon with anisotropic filtering. * * @param gl OpenGL functions wrapper * @param target Texture target * @param anisoDegree Degree of anisotropy * * @return Returns true if no error occured, false otherwise. */ bool TextureFilterAnisotropicDrawingTestCase::drawTexture(const glw::Functions& gl, GLenum target, GLfloat anisoDegree) { const GLfloat vertices2[] = { -1.0f, 0.0f, -0.5f, 0.0f, 0.0f, -4.0f, 4.0f, -2.0f, 0.0f, 1.0f, 1.0f, 0.0f, -0.5f, 1.0f, 0.0f, -2.0f, 4.0f, -2.0f, 1.0f, 1.0f }; const GLfloat vertices3[] = { -1.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, -4.0f, 4.0f, -2.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, 1.0f, 0.0f, 0.0f, -2.0f, 4.0f, -2.0f, 1.0f, 1.0f, 0.0f }; // Projection values. const GLfloat projectionMatrix[] = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -2.5f / 1.5f, -2.0f / 1.5f, 0.0f, 0.0f, -1.0f, 0.0f }; gl.viewport(0, 0, 32, 32); std::string vertexShader = m_vertex; std::string fragmentShader = m_fragment; std::string texCoordType; std::string samplerType; TextureFilterAnisotropicUtils::generateTokens(target, texCoordType, samplerType); TextureFilterAnisotropicUtils::replaceToken("<TEXCOORD_TYPE>", texCoordType.c_str(), vertexShader); TextureFilterAnisotropicUtils::replaceToken("<TEXCOORD_TYPE>", texCoordType.c_str(), fragmentShader); TextureFilterAnisotropicUtils::replaceToken("<SAMPLER_TYPE>", samplerType.c_str(), vertexShader); TextureFilterAnisotropicUtils::replaceToken("<SAMPLER_TYPE>", samplerType.c_str(), fragmentShader); if (glu::isContextTypeGLCore(m_context.getRenderContext().getType())) { TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "130", vertexShader); TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "130", fragmentShader); } else { TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "300 es", vertexShader); TextureFilterAnisotropicUtils::replaceToken("<VERSION>", "300 es", fragmentShader); } ProgramSources sources = makeVtxFragSources(vertexShader, fragmentShader); ShaderProgram program(gl, sources); if (!program.isOk()) { m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n" << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n" << vertexShader << "\n" << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n" << fragmentShader << "\n" << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage; return false; } GLuint vao; gl.genVertexArrays(1, &vao); GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays"); gl.bindVertexArray(vao); GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray"); GLuint vbo; gl.genBuffers(1, &vbo); GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers"); gl.bindBuffer(GL_ARRAY_BUFFER, vbo); GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer"); std::vector<GLfloat> vboData; vboData.resize(24); GLuint texCoordDim; if (texCoordType == "vec2") { texCoordDim = 2; deMemcpy((void*)vboData.data(), (void*)vertices2, sizeof(vertices2)); } else { texCoordDim = 3; deMemcpy((void*)vboData.data(), (void*)vertices3, sizeof(vertices3)); } gl.bufferData(GL_ARRAY_BUFFER, vboData.size() * sizeof(GLfloat), (GLvoid*)vboData.data(), GL_DYNAMIC_DRAW); GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData"); gl.useProgram(program.getProgram()); GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); GLuint matrixLocation = gl.getUniformLocation(program.getProgram(), "projectionMatrix"); GLuint texLocation = gl.getUniformLocation(program.getProgram(), "tex"); gl.activeTexture(GL_TEXTURE0); GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture"); gl.bindTexture(target, m_texture); GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture"); gl.uniformMatrix4fv(matrixLocation, 1, GL_FALSE, projectionMatrix); GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformMatrix4fv"); gl.uniform1i(texLocation, 0); GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); gl.texParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoDegree); GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterfv"); gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor"); gl.clear(GL_COLOR_BUFFER_BIT); GLU_EXPECT_NO_ERROR(gl.getError(), "glClear"); gl.enableVertexAttribArray(0); GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray"); gl.enableVertexAttribArray(1); GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray"); GLint attrLocationVertex = gl.getAttribLocation(program.getProgram(), "vertex"); GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation"); GLint attrLocationInTexCoord = gl.getAttribLocation(program.getProgram(), "inTexCoord"); GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation"); GLuint strideSize = (3 + texCoordDim) * sizeof(GLfloat); gl.vertexAttribPointer(attrLocationVertex, 3, GL_FLOAT, GL_FALSE, strideSize, DE_NULL); GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer"); gl.vertexAttribPointer(attrLocationInTexCoord, texCoordDim, GL_FLOAT, GL_FALSE, strideSize, (GLvoid*)(3 * sizeof(GLfloat))); GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer"); gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray"); gl.disableVertexAttribArray(0); GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray"); gl.disableVertexAttribArray(1); GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray"); if (vbo) { gl.deleteBuffers(1, &vbo); GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers"); } if (vao) { gl.deleteVertexArrays(1, &vao); GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays"); } return true; }
/** Verify if texParameter*, getTexParameter* queries for GL_TEXTURE_MAX_ANISOTROPY_EXT pname works as expected. * * @param gl OpenGL functions wrapper * * @return Returns true if queries test passed, false otherwise. */ bool TextureFilterAnisotropicQueriesTestCase::verifyTexParameters(const glw::Functions& gl) { GLint iValue; gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv"); // Verify initial integer value which should be equal to 1 if (iValue != 1) { m_testCtx.getLog() << tcu::TestLog::Message << "GetTexParameteriv failed. Expected value: 1, Queried value: " << iValue << tcu::TestLog::EndMessage; return false; } GLfloat fValue; gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv"); // Verify initial float value which should be equal to 1.0f if (fValue != 1.0f) { m_testCtx.getLog() << tcu::TestLog::Message << "GetTexParameterfv failed. Expected value: 1.0, Queried value: " << iValue << tcu::TestLog::EndMessage; return false; } // Set custom integer value and verify it iValue = 2; gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, iValue); GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri"); gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv"); if (iValue != 2) { m_testCtx.getLog() << tcu::TestLog::Message << "texParameteri failed. Expected value: 2, Queried value: " << iValue << tcu::TestLog::EndMessage; return false; } // Set custom float value and verify it fValue = 1.5f; gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fValue); GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterf"); gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv"); if (fValue != 1.5f) { m_testCtx.getLog() << tcu::TestLog::Message << "texParameterf failed. Expected value: 1.5, Queried value: " << fValue << tcu::TestLog::EndMessage; return false; } // Set custom integer value and verify it iValue = 1; gl.texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue); GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteriv"); gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv"); if (iValue != 1) { m_testCtx.getLog() << tcu::TestLog::Message << "texParameteriv failed. Expected value: 1, Queried value: " << iValue << tcu::TestLog::EndMessage; return false; } // Set custom float value and verify it fValue = 2.0f; gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue); GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterfv"); gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue); GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv"); if (fValue != 2.0f) { m_testCtx.getLog() << tcu::TestLog::Message << "texParameterfv failed. Expected value: 2.0, Queried value: " << fValue << tcu::TestLog::EndMessage; return false; } // Set texture filter anisotropic to 0.9f and check if INVALID_VALUE error is generated fValue = 0.9f; gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue); GLint error = gl.getError(); if (error != GL_INVALID_VALUE) { m_testCtx.getLog() << tcu::TestLog::Message << "texParameterfv failed for values less then 1.0f. Expected INVALID_VALUE error. Generated error: " << glu::getErrorName(error) << tcu::TestLog::EndMessage; return false; } return true; }