Add query and sync object handling.

* Sync objects need special handling because the identifier is an opaque
  pointer and so we can't use the existing GLResource stuff. Instead to
  handle this, we assign a GLuint ourselves and keep a mapping around
  to map GLuint<->GLsync. Everything else works as usual from the GLuint
This commit is contained in:
Baldur Karlsson
2014-06-18 16:07:58 +01:00
parent 72de770e22
commit 9015b139c0
12 changed files with 361 additions and 1 deletions
+1
View File
@@ -48,6 +48,7 @@ driver/gl/wrappers/gl_debug_funcs.o \
driver/gl/wrappers/gl_draw_funcs.o \
driver/gl/wrappers/gl_framebuffer_funcs.o \
driver/gl/wrappers/gl_get_funcs.o \
driver/gl/wrappers/gl_query_funcs.o \
driver/gl/wrappers/gl_sampler_funcs.o \
driver/gl/wrappers/gl_shader_funcs.o \
driver/gl/wrappers/gl_state_funcs.o \
+8
View File
@@ -115,6 +115,14 @@ enum GLChunkType
USE_PROGRAMSTAGES,
BIND_PROGRAMPIPE,
FENCE_SYNC,
CLIENTWAIT_SYNC,
WAIT_SYNC,
GEN_QUERIES,
BEGIN_QUERY,
END_QUERY,
CLEAR_COLOR,
CLEAR_DEPTH,
CLEAR,
+8
View File
@@ -72,6 +72,14 @@ const char *GLChunkNames[] =
"glUseProgramStages",
"glBindProgramPipeline",
"glFenceSync",
"glClientWaitSync",
"glWaitSync",
"glGenQueries",
"glBeginQuery",
"glEndQuery",
"glClearColor",
"glClearDepth",
"glClear",
+14
View File
@@ -350,6 +350,20 @@ class WrappedOpenGL
IMPLEMENT_FUNCTION_SERIALISED(void, glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf));
IMPLEMENT_FUNCTION_SERIALISED(void, glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message));
IMPLEMENT_FUNCTION_SERIALISED(void, glPopDebugGroup());
bool Serialise_glFenceSync(GLsync real, GLenum condition, GLbitfield flags);
GLsync glFenceSync(GLenum condition, GLbitfield flags);
IMPLEMENT_FUNCTION_SERIALISED(GLenum, glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout));
IMPLEMENT_FUNCTION_SERIALISED(void, glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout));
IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteSync(GLsync sync));
IMPLEMENT_FUNCTION_SERIALISED(void, glGenQueries(GLsizei n, GLuint *ids));
IMPLEMENT_FUNCTION_SERIALISED(void, glBeginQuery(GLenum target, GLuint id));
IMPLEMENT_FUNCTION_SERIALISED(void, glEndQuery(GLenum target));
IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params));
IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params));
IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteQueries(GLsizei n, const GLuint *ids));
IMPLEMENT_FUNCTION_SERIALISED(void, glActiveTexture(GLenum texture));
IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width));
IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height));
+10
View File
@@ -175,6 +175,16 @@ struct GLHookSet
PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
PFNGLFENCESYNCPROC glFenceSync;
PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
PFNGLWAITSYNCPROC glWaitSync;
PFNGLDELETESYNCPROC glDeleteSync;
PFNGLGENQUERIESPROC glGenQueries;
PFNGLBEGINQUERYPROC glBeginQuery;
PFNGLENDQUERYPROC glEndQuery;
PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
PFNGLDELETEQUERIESPROC glDeleteQueries;
PFNGLBUFFERDATAPROC glBufferData;
PFNGLBINDBUFFERBASEPROC glBindBufferBase;
PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+20
View File
@@ -189,6 +189,16 @@
HookExtension(PFNGLFRAMEBUFFERTEXTUREPROC, glFramebufferTexture); \
HookExtension(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers); \
HookExtension(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC, glGetFramebufferAttachmentParameteriv); \
HookExtension(PFNGLFENCESYNCPROC, glFenceSync); \
HookExtension(PFNGLCLIENTWAITSYNCPROC, glClientWaitSync); \
HookExtension(PFNGLWAITSYNCPROC, glWaitSync); \
HookExtension(PFNGLDELETESYNCPROC, glDeleteSync); \
HookExtension(PFNGLGENQUERIESPROC, glGenQueries); \
HookExtension(PFNGLBEGINQUERYPROC, glBeginQuery); \
HookExtension(PFNGLENDQUERYPROC, glEndQuery); \
HookExtension(PFNGLGETQUERYOBJECTUI64VPROC, glGetQueryObjectui64v); \
HookExtension(PFNGLGETQUERYOBJECTUIVPROC, glGetQueryObjectuiv); \
HookExtension(PFNGLDELETEQUERIESPROC, glDeleteQueries); \
HookExtension(PFNGLBUFFERDATAPROC, glBufferData); \
HookExtension(PFNGLBINDBUFFERBASEPROC, glBindBufferBase); \
HookExtension(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange); \
@@ -467,6 +477,16 @@
HookWrapper4(void, glFramebufferTexture, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level); \
HookWrapper2(void, glDeleteFramebuffers, GLsizei, n, const GLuint *, framebuffers); \
HookWrapper4(void, glGetFramebufferAttachmentParameteriv, GLenum, target, GLenum, attachment, GLenum, pname, GLint *, params); \
HookWrapper2(GLsync, glFenceSync, GLenum, condition, GLbitfield, flags); \
HookWrapper3(GLenum, glClientWaitSync, GLsync, sync, GLbitfield, flags, GLuint64, timeout); \
HookWrapper3(void, glWaitSync, GLsync, sync, GLbitfield, flags, GLuint64, timeout); \
HookWrapper1(void, glDeleteSync, GLsync, sync); \
HookWrapper2(void, glGenQueries, GLsizei, n, GLuint *, ids); \
HookWrapper2(void, glBeginQuery, GLenum, target, GLuint, id); \
HookWrapper1(void, glEndQuery, GLenum, target); \
HookWrapper3(void, glGetQueryObjectui64v, GLuint, id, GLenum, pname, GLuint64 *, params); \
HookWrapper3(void, glGetQueryObjectuiv, GLuint, id, GLenum, pname, GLuint *, params); \
HookWrapper2(void, glDeleteQueries, GLsizei, n, const GLuint *, ids); \
HookWrapper4(void, glBufferData, GLenum, target, GLsizeiptr, size, const void *, data, GLenum, usage); \
HookWrapper3(void, glBindBufferBase, GLenum, target, GLuint, index, GLuint, buffer); \
HookWrapper5(void, glBindBufferRange, GLenum, target, GLuint, index, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \
+26 -1
View File
@@ -34,7 +34,7 @@ class WrappedOpenGL;
class GLResourceManager : public ResourceManager<GLResource, GLResourceRecord>
{
public:
GLResourceManager(WrappedOpenGL *gl) : m_GL(gl) {}
GLResourceManager(WrappedOpenGL *gl) : m_GL(gl), m_SyncName(1) {}
~GLResourceManager() {}
void Shutdown()
@@ -115,6 +115,25 @@ class GLResourceManager : public ResourceManager<GLResource, GLResourceRecord>
return ResourceManager::GetResourceRecord(GetID(res));
}
void RegisterSync(GLsync sync, GLuint &name, ResourceId &id)
{
name = (GLuint)Atomic::Inc64(&m_SyncName);
id = RegisterResource(SyncRes(name));
m_SyncIDs[sync] = id;
m_CurrentSyncs[name] = sync;
}
GLsync GetSync(GLuint name)
{
return m_CurrentSyncs[name];
}
ResourceId GetSyncID(GLsync sync)
{
return m_SyncIDs[sync];
}
private:
bool SerialisableResource(ResourceId id, GLResourceRecord *record);
@@ -131,6 +150,12 @@ class GLResourceManager : public ResourceManager<GLResource, GLResourceRecord>
map<GLResource, ResourceId> m_CurrentResourceIds;
// sync objects must be treated differently as they're not GLuint names, but pointer sized.
// We manually give them GLuint names so they're otherwise namespaced as (eResSync, GLuint)
map<GLsync, ResourceId> m_SyncIDs;
map<GLuint, GLsync> m_CurrentSyncs;
volatile int64_t m_SyncName;
WrappedOpenGL *m_GL;
};
+4
View File
@@ -43,6 +43,8 @@ enum GLNamespace
eResShader,
eResProgram,
eResProgramPipe,
eResQuery,
eResSync,
};
enum GLSpecialResource
@@ -86,6 +88,8 @@ inline GLResource VertexArrayRes(GLuint i) { return GLResource(eResVertexArray,
inline GLResource ShaderRes(GLuint i) { return GLResource(eResShader, i); }
inline GLResource ProgramRes(GLuint i) { return GLResource(eResProgram, i); }
inline GLResource ProgramPipeRes(GLuint i) { return GLResource(eResProgramPipe, i); }
inline GLResource QueryRes(GLuint i) { return GLResource(eResQuery, i); }
inline GLResource SyncRes(GLuint i) { return GLResource(eResSync, i); }
struct GLResourceRecord : public ResourceRecord
{
@@ -154,6 +154,16 @@ void WrappedOpenGL::glGetBufferSubData(GLenum target, GLintptr offset, GLsizeipt
m_Real.glGetBufferSubData(target, offset, size, data);
}
void WrappedOpenGL::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
{
m_Real.glGetQueryObjectuiv(id, pname, params);
}
void WrappedOpenGL::glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
{
m_Real.glGetQueryObjectui64v(id, pname, params);
}
const GLubyte *WrappedOpenGL::glGetString(GLenum name)
{
if(name == GL_EXTENSIONS)
@@ -0,0 +1,256 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2014 Crytek
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "common/common.h"
#include "common/string_utils.h"
#include "../gl_driver.h"
bool WrappedOpenGL::Serialise_glFenceSync(GLsync real, GLenum condition, GLbitfield flags)
{
SERIALISE_ELEMENT(GLenum, Condition, condition);
SERIALISE_ELEMENT(uint32_t, Flags, flags);
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(real));
if(m_State < WRITING)
{
GLsync real = m_Real.glFenceSync(Condition, Flags);
GLuint name = 0;
ResourceId liveid = ResourceId();
GetResourceManager()->RegisterSync(real, name, liveid);
GLResource res = SyncRes(name);
ResourceId live = m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
}
return true;
}
GLsync WrappedOpenGL::glFenceSync(GLenum condition, GLbitfield flags)
{
GLsync sync = m_Real.glFenceSync(condition, flags);
GLuint name = 0;
ResourceId id = ResourceId();
GetResourceManager()->RegisterSync(sync, name, id);
GLResource res = SyncRes(name);
if(m_State == WRITING_CAPFRAME)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(FENCE_SYNC);
Serialise_glFenceSync(sync, condition, flags);
chunk = scope.Get();
}
m_ContextRecord->AddChunk(chunk);
}
else
{
GetResourceManager()->AddLiveResource(id, res);
}
return sync;
}
bool WrappedOpenGL::Serialise_glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
SERIALISE_ELEMENT(uint32_t, Flags, flags);
SERIALISE_ELEMENT(uint64_t, Timeout, timeout);
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(sync));
if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
glClientWaitSync(GetResourceManager()->GetSync(res.name), Flags, Timeout);
}
return true;
}
GLenum WrappedOpenGL::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
GLenum ret = m_Real.glClientWaitSync(sync, flags, timeout);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(CLIENTWAIT_SYNC);
Serialise_glClientWaitSync(sync, flags, timeout);
m_ContextRecord->AddChunk(scope.Get());
}
return ret;
}
bool WrappedOpenGL::Serialise_glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
SERIALISE_ELEMENT(uint32_t, Flags, flags);
SERIALISE_ELEMENT(uint64_t, Timeout, timeout);
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(sync));
if(m_State < WRITING)
{
GLResource res = GetResourceManager()->GetLiveResource(id);
glWaitSync(GetResourceManager()->GetSync(res.name), Flags, Timeout);
}
return true;
}
void WrappedOpenGL::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
m_Real.glWaitSync(sync, flags, timeout);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(WAIT_SYNC);
Serialise_glWaitSync(sync, flags, timeout);
m_ContextRecord->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glDeleteSync(GLsync sync)
{
m_Real.glDeleteSync(sync);
ResourceId id = GetResourceManager()->GetSyncID(sync);
GetResourceManager()->UnregisterResource(GetResourceManager()->GetCurrentResource(id));
}
bool WrappedOpenGL::Serialise_glGenQueries(GLsizei n, GLuint* ids)
{
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(*ids)));
if(m_State == READING)
{
GLuint real = 0;
m_Real.glGenSamplers(1, &real);
GLResource res = QueryRes(real);
ResourceId live = m_ResourceManager->RegisterResource(res);
GetResourceManager()->AddLiveResource(id, res);
}
return true;
}
void WrappedOpenGL::glGenQueries(GLsizei count, GLuint *ids)
{
m_Real.glGenSamplers(count, ids);
for(GLsizei i=0; i < count; i++)
{
GLResource res = QueryRes(ids[i]);
ResourceId id = GetResourceManager()->RegisterResource(res);
if(m_State >= WRITING)
{
Chunk *chunk = NULL;
{
SCOPED_SERIALISE_CONTEXT(GEN_QUERIES);
Serialise_glGenQueries(1, ids+i);
chunk = scope.Get();
}
GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
RDCASSERT(record);
record->AddChunk(chunk);
}
else
{
GetResourceManager()->AddLiveResource(id, res);
}
}
}
bool WrappedOpenGL::Serialise_glBeginQuery(GLenum target, GLuint qid)
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(qid)));
if(m_State < WRITING)
{
glBeginQuery(Target, GetResourceManager()->GetLiveResource(id).name);
}
return true;
}
void WrappedOpenGL::glBeginQuery(GLenum target, GLuint id)
{
m_Real.glBeginQuery(target, id);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY);
Serialise_glBeginQuery(target, id);
m_ContextRecord->AddChunk(scope.Get());
}
}
bool WrappedOpenGL::Serialise_glEndQuery(GLenum target)
{
SERIALISE_ELEMENT(GLenum, Target, target);
if(m_State < WRITING)
{
glEndQuery(Target);
}
return true;
}
void WrappedOpenGL::glEndQuery(GLenum target)
{
m_Real.glEndQuery(target);
if(m_State == WRITING_CAPFRAME)
{
SCOPED_SERIALISE_CONTEXT(END_QUERY);
Serialise_glEndQuery(target);
m_ContextRecord->AddChunk(scope.Get());
}
}
void WrappedOpenGL::glDeleteQueries(GLsizei n, const GLuint *ids)
{
m_Real.glDeleteQueries(n, ids);
for(GLsizei i=0; i < n; i++)
GetResourceManager()->UnregisterResource(QueryRes(ids[i]));
}
+1
View File
@@ -339,6 +339,7 @@
<ClCompile Include="driver\gl\wrappers\gl_draw_funcs.cpp" />
<ClCompile Include="driver\gl\wrappers\gl_framebuffer_funcs.cpp" />
<ClCompile Include="driver\gl\wrappers\gl_get_funcs.cpp" />
<ClCompile Include="driver\gl\wrappers\gl_query_funcs.cpp" />
<ClCompile Include="driver\gl\wrappers\gl_sampler_funcs.cpp" />
<ClCompile Include="driver\gl\wrappers\gl_shader_funcs.cpp" />
<ClCompile Include="driver\gl\wrappers\gl_state_funcs.cpp" />
+3
View File
@@ -503,6 +503,9 @@
<ClCompile Include="driver\gl\wrappers\gl_get_funcs.cpp">
<Filter>Drivers\OpenGL\Function Wrappers</Filter>
</ClCompile>
<ClCompile Include="driver\gl\wrappers\gl_query_funcs.cpp">
<Filter>Drivers\OpenGL\Function Wrappers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="os\win32\comexport.def">