Commit 92b5fccd by Mohan Maiya Committed by Commit Bot

Handle nullptr in GetQueryObjectParameter()

There are applications that disable validation using EGL_CONTEXT_OPENGL_NO_ERROR_KHR extension. In such usecases the GetQueryObjectParameter() method needs to account for the possibility that the query object has not yet been created. Bug: angleproject:5704 Tests: angle_end2end_tests --gtest_filter=QueryObjectTest* Change-Id: Ib9e1cb32a6d64f2772124178223cf07cbb84691b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2729298Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
parent faa3915e
......@@ -67,7 +67,25 @@ egl::ShareGroup *AllocateOrGetShareGroup(egl::Display *display, const gl::Contex
template <typename T>
angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLenum pname, T *params)
{
ASSERT(query != nullptr || pname == GL_QUERY_RESULT_AVAILABLE_EXT);
if (!query)
{
// Some applications call into glGetQueryObjectuiv(...) prior to calling glBeginQuery(...)
// This wouldn't be an issue since the validation layer will handle such a usecases but when
// the app enables EGL_KHR_create_context_no_error extension, we skip the validation layer.
switch (pname)
{
case GL_QUERY_RESULT_EXT:
*params = 0;
break;
case GL_QUERY_RESULT_AVAILABLE_EXT:
*params = GL_FALSE;
break;
default:
UNREACHABLE();
return angle::Result::Stop;
}
return angle::Result::Continue;
}
switch (pname)
{
......
......@@ -108,6 +108,7 @@ angle_end2end_tests_sources = [
"gl_tests/ProgramParameterTest.cpp",
"gl_tests/ProgramPipelineTest.cpp",
"gl_tests/ProvokingVertexTest.cpp",
"gl_tests/QueryObjectValidation.cpp",
"gl_tests/ReadOnlyFeedbackLoopTest.cpp",
"gl_tests/ReadPixelsTest.cpp",
"gl_tests/RenderbufferMultisampleTest.cpp",
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// QueryObjectValidation.cpp : Tests between gl.*Query.* functions and interactions with
// EGL_CONTEXT_OPENGL_NO_ERROR_KHR
#include <gtest/gtest.h>
#include "test_utils/ANGLETest.h"
#include "util/EGLWindow.h"
#include "util/test_utils.h"
namespace angle
{
using QueryObjectTestParams = std::tuple<angle::PlatformParameters, bool>;
std::string PrintToStringParamName(const ::testing::TestParamInfo<QueryObjectTestParams> &info)
{
std::stringstream ss;
ss << std::get<0>(info.param);
if (std::get<1>(info.param))
{
ss << "__ValidationDisabled";
}
else
{
ss << "__ValidationEnabled";
}
return ss.str();
}
class QueryObjectTest : public ANGLETestWithParam<QueryObjectTestParams>
{
protected:
QueryObjectTest() : mQueryObjectName(0), mQueryResult(false)
{
setNoErrorEnabled(testing::get<1>(GetParam()));
}
void createQuery()
{
glGenQueries(1, &mQueryObjectName);
ASSERT_NE(mQueryObjectName, (GLuint)0u);
ASSERT_GL_NO_ERROR();
}
void testSetUp() override { createQuery(); }
void testTearDown() override
{
if (mQueryObjectName)
{
glDeleteQueries(1, &mQueryObjectName);
}
}
GLuint mQueryObjectName = 0;
GLuint mQueryResult = 0;
};
class QueryObjectTestES32 : public QueryObjectTest
{};
// Test if a generated query is a query before glBeginQuery
TEST_P(QueryObjectTest, QueryObjectIsQuery)
{
GLboolean isQueryResult = glIsQuery(mQueryObjectName);
ASSERT_GL_NO_ERROR();
ASSERT_FALSE(isQueryResult);
}
// Negative test for glGetQueryObjectuiv before glBegin with GL_QUERY_RESULT
TEST_P(QueryObjectTest, QueryObjectResultBeforeBegin)
{
glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT, &mQueryResult);
bool isNoError = testing::get<1>(GetParam());
if (isNoError)
{
ASSERT_GL_NO_ERROR();
}
else
{
ASSERT_EQ(glGetError(), (GLenum)GL_INVALID_OPERATION);
}
}
// Negative test for glGetQueryObjectuiv before glBegin with GL_QUERY_RESULT_AVAILABLE
TEST_P(QueryObjectTest, QueryObjectResultAvailableBeforeBegin)
{
glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT_AVAILABLE, &mQueryResult);
bool isNoError = testing::get<1>(GetParam());
if (isNoError)
{
ASSERT_GL_NO_ERROR();
}
else
{
ASSERT_EQ(glGetError(), (GLenum)GL_INVALID_OPERATION);
}
}
// Test glGetQueryObjectuiv after glEndQuery
TEST_P(QueryObjectTest, QueryObjectResultAfterEnd)
{
glBeginQuery(GL_ANY_SAMPLES_PASSED, mQueryObjectName);
ASSERT_GL_NO_ERROR();
glEndQuery(GL_ANY_SAMPLES_PASSED);
ASSERT_GL_NO_ERROR();
glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT_AVAILABLE, &mQueryResult);
}
// Test glGetQueryObjectuiv after glEndQuery with GL_PRIMITIVES_GENERATED
TEST_P(QueryObjectTestES32, QueryObjectResultAfterEndPrimitivesGenerated)
{
// TODO(anglebug.com/5430): Allow GL_PRIMITIVES_GENERATED query objects
// when transform feedback is not active
ANGLE_SKIP_TEST_IF(IsVulkan());
glBeginQuery(GL_PRIMITIVES_GENERATED, mQueryObjectName);
ASSERT_GL_NO_ERROR();
glEndQuery(GL_PRIMITIVES_GENERATED);
ASSERT_GL_NO_ERROR();
while (mQueryResult != GL_TRUE)
{
glGetQueryObjectuiv(mQueryObjectName, GL_QUERY_RESULT_AVAILABLE, &mQueryResult);
ASSERT_GL_NO_ERROR();
angle::Sleep(50);
}
GLboolean isQueryResult = glIsQuery(mQueryObjectName);
ASSERT_GL_NO_ERROR();
ASSERT_TRUE(isQueryResult);
}
static const bool noErrorFlags[] = {true, false};
ANGLE_INSTANTIATE_TEST_COMBINE_1(QueryObjectTest,
PrintToStringParamName,
testing::ValuesIn(noErrorFlags),
ANGLE_ALL_TEST_PLATFORMS_ES3);
ANGLE_INSTANTIATE_TEST_COMBINE_1(QueryObjectTestES32,
PrintToStringParamName,
testing::ValuesIn(noErrorFlags),
ANGLE_ALL_TEST_PLATFORMS_ES32);
// This test suite is not instantiated on some OSes.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(QueryObjectTestES32);
} // namespace angle
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment