mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 12:48:32 +09:00
[Feat] (MG_Impl): implement glCreateQueries and stop treating a reserved name as a query
glGenQueries only reserves names; a name becomes a query object when it is first used with BeginQuery or QueryCounter (GL 4.6 core 4.2.1). MobileGL created the live object eagerly at glGenQueries time and glIsQuery reported every reserved name as an object, with a comment noting the shortcut. The registry already distinguished the two states -- a target of 0 means the name has never been used -- so glIsQuery now consults it, and a name that came from glCreateQueries carries a flag saying it is an object regardless. glCreateQueries itself was a stub. It creates the objects outright with their target already fixed, which is the whole point of the DSA form: there is no binding step to infer the target from later.
This commit is contained in:
@@ -1097,7 +1097,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexArrayIndexediv, GLuint vaobj, GLuin
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetVertexArrayIndexed64iv, GLuint vaobj, GLuint index, GLenum pname, GLint64* param) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetVertexArrayIndexed64iv, vaobj, index, pname, param)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, CreateSamplers, GLsizei n, GLuint* samplers) DECLARE_GL_FUNCTION_END_NO_RETURN(void, CreateSamplers, n, samplers)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, CreateProgramPipelines, GLsizei n, GLuint* pipelines) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CreateProgramPipelines, n, pipelines)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, CreateQueries, GLenum target, GLsizei n, GLuint* ids) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, CreateQueries, target, n, ids)
|
||||
DECLARE_GL_FUNCTION_HEAD(void, CreateQueries, GLenum target, GLsizei n, GLuint* ids) DECLARE_GL_FUNCTION_END_NO_RETURN(void, CreateQueries, target, n, ids)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryBufferObjecti64v, GLuint id, GLuint buffer, GLenum pname, GLintptr offset) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetQueryBufferObjecti64v, id, buffer, pname, offset)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryBufferObjectiv, GLuint id, GLuint buffer, GLenum pname, GLintptr offset) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetQueryBufferObjectiv, id, buffer, pname, offset)
|
||||
DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryBufferObjectui64v, GLuint id, GLuint buffer, GLenum pname, GLintptr offset) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetQueryBufferObjectui64v, id, buffer, pname, offset)
|
||||
|
||||
@@ -23,6 +23,9 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
struct QueryObject {
|
||||
GLuint id = 0;
|
||||
GLenum target = 0; // 0 = gen'd but never used with BeginQuery/QueryCounter
|
||||
// glCreateQueries makes the object outright; glGenQueries only reserves the name,
|
||||
// and the object appears when the name is first used (GL 4.6 core 4.2.1).
|
||||
Bool created = false;
|
||||
MG_Backend::BackendQueryHandle backendHandle = nullptr;
|
||||
Bool active = false;
|
||||
Bool ended = false;
|
||||
@@ -177,6 +180,41 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
}
|
||||
}
|
||||
|
||||
// glCreateQueries differs from glGenQueries in creating the objects outright, with their
|
||||
// target already fixed and the rest of their state at the defaults (GL 4.6 core 4.2.1).
|
||||
void CreateQueries(GLenum target, GLsizei n, GLuint* ids) {
|
||||
switch (target) {
|
||||
case GL_SAMPLES_PASSED:
|
||||
case GL_ANY_SAMPLES_PASSED:
|
||||
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
|
||||
case GL_TIME_ELAPSED:
|
||||
case GL_TIMESTAMP:
|
||||
case GL_PRIMITIVES_GENERATED:
|
||||
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
|
||||
break;
|
||||
default:
|
||||
RecordQueryError(ErrorCode::InvalidEnum, __FUNCTION__, "Query target is not accepted.");
|
||||
return;
|
||||
}
|
||||
if (n < 0) {
|
||||
RecordQueryError(ErrorCode::InvalidValue, __FUNCTION__, "n cannot be negative.");
|
||||
return;
|
||||
}
|
||||
if (!ids) {
|
||||
return;
|
||||
}
|
||||
const std::lock_guard<std::mutex> lock(g_queryObjectsMutex);
|
||||
for (GLsizei i = 0; i < n; ++i) {
|
||||
const GLuint id = g_nextQueryId++;
|
||||
auto* queryObject = new QueryObject;
|
||||
queryObject->id = id;
|
||||
queryObject->target = target;
|
||||
queryObject->created = true;
|
||||
g_liveQueryObjects[id] = queryObject;
|
||||
ids[i] = id;
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteQueries(GLsizei n, const GLuint* ids) {
|
||||
if (n < 0) {
|
||||
RecordQueryError(ErrorCode::InvalidValue, __FUNCTION__, "n cannot be negative.");
|
||||
@@ -228,9 +266,11 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
return GL_FALSE;
|
||||
}
|
||||
const std::lock_guard<std::mutex> lock(g_queryObjectsMutex);
|
||||
// Gen'd ids count as query objects here: the registry creates live
|
||||
// objects at GenQueries time.
|
||||
return FindQueryObjectLocked(id) != nullptr ? GL_TRUE : GL_FALSE;
|
||||
// A name from glGenQueries is not yet a query object: it becomes one when it is first
|
||||
// used with BeginQuery/QueryCounter (which is what a non-zero target records), or
|
||||
// immediately if it came from glCreateQueries.
|
||||
const auto* queryObject = FindQueryObjectLocked(id);
|
||||
return (queryObject != nullptr && (queryObject->created || queryObject->target != 0)) ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
|
||||
void BeginQuery(GLenum target, GLuint id) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace MobileGL::MG_Impl::GLImpl {
|
||||
void GenQueries(GLsizei n, GLuint* ids);
|
||||
void CreateQueries(GLenum target, GLsizei n, GLuint* ids);
|
||||
void DeleteQueries(GLsizei n, const GLuint* ids);
|
||||
GLboolean IsQuery(GLuint id);
|
||||
void BeginQuery(GLenum target, GLuint id);
|
||||
|
||||
Reference in New Issue
Block a user