First attempt to implement Map/Unmap

This commit is contained in:
baldurk
2014-06-01 10:01:10 +01:00
parent 60ca0d065b
commit 932995da56
6 changed files with 242 additions and 14 deletions
+1
View File
@@ -177,6 +177,7 @@ enum GLChunkType
BIND_BUFFER_BASE,
BIND_BUFFER_RANGE,
BUFFERDATA,
UNMAP,
GEN_VERTEXARRAY,
BIND_VERTEXARRAY,
VERTEXATTRIBPOINTER,
+207 -3
View File
@@ -1621,7 +1621,19 @@ bool WrappedOpenGL::Serialise_glBufferData(GLenum target, GLsizeiptr size, const
{
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size);
byte *dummy = NULL;
if(m_State >= WRITING && data == NULL)
{
dummy = new byte[size];
data = dummy;
}
SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize);
uint64_t offs = m_pSerialiser->GetOffset();
SERIALISE_ELEMENT(GLenum, Usage, usage);
SERIALISE_ELEMENT(ResourceId, id, m_BufferRecord[BufferIdx(target)]->GetResourceID());
@@ -1635,6 +1647,13 @@ bool WrappedOpenGL::Serialise_glBufferData(GLenum target, GLsizeiptr size, const
SAFE_DELETE_ARRAY(bytes);
}
else if(m_State >= WRITING)
{
m_BufferRecord[BufferIdx(target)]->SetDataOffset(offs - Bytesize);
}
if(dummy)
delete[] dummy;
return true;
}
@@ -1652,7 +1671,11 @@ void WrappedOpenGL::glBufferData(GLenum target, GLsizeiptr size, const void *dat
SCOPED_SERIALISE_CONTEXT(BUFFERDATA);
Serialise_glBufferData(target, size, data, usage);
m_BufferRecord[idx]->AddChunk(scope.Get());
Chunk *chunk = scope.Get();
m_BufferRecord[idx]->AddChunk(chunk);
m_BufferRecord[idx]->SetDataPtr(chunk->GetData());
m_BufferRecord[idx]->Length = size;
}
}
@@ -1718,17 +1741,198 @@ void *WrappedOpenGL::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr
{
if(m_State >= WRITING)
{
RDCUNIMPLEMENTED();
// haven't implemented non-invalidating write maps
if((access & (GL_MAP_INVALIDATE_BUFFER_BIT|GL_MAP_INVALIDATE_RANGE_BIT|GL_MAP_READ_BIT)) == 0)
RDCUNIMPLEMENTED();
// haven't implemented coherent/persistent bits
if((access & (GL_MAP_COHERENT_BIT|GL_MAP_PERSISTENT_BIT)) != 0)
RDCUNIMPLEMENTED();
m_BufferRecord[BufferIdx(target)]->Map.offset = offset;
m_BufferRecord[BufferIdx(target)]->Map.length = length;
m_BufferRecord[BufferIdx(target)]->Map.access = access;
if((access & GL_MAP_READ_BIT) != 0)
{
byte *ptr = m_BufferRecord[BufferIdx(target)]->GetDataPtr();
if(ptr == NULL)
{
RDCWARN("Mapping buffer that hasn't been allocated");
m_BufferRecord[BufferIdx(target)]->Map.status = GLResourceRecord::Mapped_Read_Real;
return m_Real.glMapBufferRange(target, offset, length, access);
}
ptr += offset;
m_Real.glGetBufferSubData(target, offset, length, ptr);
m_BufferRecord[BufferIdx(target)]->Map.status = GLResourceRecord::Mapped_Read;
return ptr;
}
byte *ptr = m_BufferRecord[BufferIdx(target)]->GetDataPtr();
if(ptr == NULL)
{
RDCWARN("Mapping buffer that hasn't been allocated");
ptr = (byte *)m_Real.glMapBufferRange(target, offset, length, access);
m_BufferRecord[BufferIdx(target)]->Map.ptr = ptr;
m_BufferRecord[BufferIdx(target)]->Map.status = GLResourceRecord::Mapped_Write_Real;
}
else
{
if(m_State == WRITING_CAPFRAME)
{
ptr = new byte[length];
m_BufferRecord[BufferIdx(target)]->Map.ptr = ptr;
m_BufferRecord[BufferIdx(target)]->Map.status = GLResourceRecord::Mapped_Write_Alloc;
}
else
{
ptr += offset;
m_BufferRecord[BufferIdx(target)]->Map.ptr = ptr;
m_BufferRecord[BufferIdx(target)]->Map.status = GLResourceRecord::Mapped_Write;
}
}
return ptr;
}
return m_Real.glMapBufferRange(target, offset, length, access);
}
bool WrappedOpenGL::Serialise_glUnmapBuffer(GLenum target)
{
GLResourceRecord *record = NULL;
if(m_State >= WRITING)
record = m_BufferRecord[BufferIdx(target)];
SERIALISE_ELEMENT(GLenum, Target, target);
SERIALISE_ELEMENT(ResourceId, bufID, record->GetResourceID());
SERIALISE_ELEMENT(uint64_t, offs, record->Map.offset);
SERIALISE_ELEMENT(uint64_t, len, record->Map.length);
uint64_t bufBindStart = 0;
if(m_State >= WRITING)
{
if(Target == eGL_ATOMIC_COUNTER_BUFFER)
m_Real.glGetInteger64i_v(eGL_ATOMIC_COUNTER_BUFFER_START, 0, (GLint64 *)&bufBindStart);
if(Target == eGL_SHADER_STORAGE_BUFFER)
m_Real.glGetInteger64i_v(eGL_SHADER_STORAGE_BUFFER_START, 0, (GLint64 *)&bufBindStart);
if(Target == eGL_TRANSFORM_FEEDBACK_BUFFER)
m_Real.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_START, 0, (GLint64 *)&bufBindStart);
if(Target == eGL_UNIFORM_BUFFER)
m_Real.glGetInteger64i_v(eGL_UNIFORM_BUFFER_START, 0, (GLint64 *)&bufBindStart);
}
SERIALISE_ELEMENT(uint64_t, bufOffs, bufBindStart);
SERIALISE_ELEMENT_BUF(byte *, data, record->Map.ptr, (size_t)len);
if(m_State < WRITING ||
(m_State >= WRITING &&
(record->Map.status == GLResourceRecord::Mapped_Write || record->Map.status == GLResourceRecord::Mapped_Write_Alloc)
)
)
{
GLuint oldBuf = 0;
GLuint64 oldBufBase = 0;
GLuint64 oldBufSize = 0;
if(m_State == READING)
{
GLResource res = GetResourceManager()->GetLiveResource(bufID);
m_Real.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, 0, (GLint *)&oldBuf);
m_Real.glGetInteger64i_v(eGL_UNIFORM_BUFFER_START, 0, (GLint64 *)&oldBufBase);
m_Real.glGetInteger64i_v(eGL_UNIFORM_BUFFER_SIZE, 0, (GLint64 *)&oldBufSize);
m_Real.glBindBufferRange(eGL_UNIFORM_BUFFER, 0, res.name, (GLintptr)bufOffs, (GLsizeiptr)len);
}
void *ptr = m_Real.glMapBufferRange(Target, (GLintptr)offs, (GLsizeiptr)len, GL_MAP_WRITE_BIT);
memcpy(ptr, data, (size_t)len);
m_Real.glUnmapBuffer(Target);
if(m_State == READING)
{
m_Real.glBindBufferRange(eGL_UNIFORM_BUFFER, 0, oldBuf, (GLintptr)oldBufBase, (GLsizeiptr)oldBufSize);
}
}
if(m_State < WRITING)
delete[] data;
return true;
}
GLboolean WrappedOpenGL::glUnmapBuffer(GLenum target)
{
if(m_State >= WRITING)
{
RDCUNIMPLEMENTED();
RDCASSERT(m_BufferRecord[BufferIdx(target)]);
auto status = m_BufferRecord[BufferIdx(target)]->Map.status;
GLboolean ret = GL_TRUE;
switch(status)
{
case GLResourceRecord::Unmapped:
RDCERR("Unmapped buffer being passed to glUnmapBuffer");
break;
case GLResourceRecord::Mapped_Read:
// can ignore
break;
case GLResourceRecord::Mapped_Read_Real:
// need to do real unmap
ret = m_Real.glUnmapBuffer(target);
break;
case GLResourceRecord::Mapped_Write:
{
if(m_State == WRITING_CAPFRAME)
RDCWARN("Failed to cap frame - uncapped Map/Unmap");
SCOPED_SERIALISE_CONTEXT(UNMAP);
Serialise_glUnmapBuffer(target);
if(m_State == WRITING_CAPFRAME)
m_ContextRecord->AddChunk(scope.Get());
else
m_BufferRecord[BufferIdx(target)]->AddChunk(scope.Get());
break;
}
case GLResourceRecord::Mapped_Write_Alloc:
{
SCOPED_SERIALISE_CONTEXT(UNMAP);
Serialise_glUnmapBuffer(target);
if(m_State == WRITING_CAPFRAME)
m_ContextRecord->AddChunk(scope.Get());
delete[] m_BufferRecord[BufferIdx(target)]->Map.ptr;
break;
}
case GLResourceRecord::Mapped_Write_Real:
RDCWARN("Throwing away map contents as we don't have datastore allocated");
RDCWARN("Could init chunk here using known data (although maybe it's only partial)");
ret = m_Real.glUnmapBuffer(target);
break;
}
m_BufferRecord[BufferIdx(target)]->Map.status = GLResourceRecord::Unmapped;
return ret;
}
return m_Real.glUnmapBuffer(target);
+4
View File
@@ -134,6 +134,7 @@ const char *GLChunkNames[] =
"glBindBufferBase",
"glBindBufferRange",
"glBufferData",
"glUnmapBuffer",
"glGenVertexArrays",
"glBindVertexArray",
"glVertexAttribPointer",
@@ -1156,6 +1157,9 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context)
case BUFFERDATA:
Serialise_glBufferData(eGL_UNKNOWN_ENUM, 0, NULL, eGL_UNKNOWN_ENUM);
break;
case UNMAP:
Serialise_glUnmapBuffer(eGL_UNKNOWN_ENUM);
break;
case GEN_VERTEXARRAY:
Serialise_glGenVertexArrays(0, NULL);
break;
+2 -2
View File
@@ -33,13 +33,13 @@ struct GLHookSet
// ++ dllexport
PFNGLBINDTEXTUREPROC glBindTexture;
PFNGLBLENDFUNCPROC glBlendFunc;
PFNGLBLENDCOLORPROC glBlendColor;
PFNGLCLEARPROC glClear;
PFNGLCLEARCOLORPROC glClearColor;
PFNGLCLEARDEPTHPROC glClearDepth;
PFNGLCOLORMASKPROC glColorMask;
PFNGLCULLFACEPROC glCullFace;
PFNGLDEPTHFUNCPROC glDepthFunc;
PFNGLDEPTHMASKPROC glDepthMask;
PFNGLDISABLEPROC glDisable;
PFNGLDRAWARRAYSPROC glDrawArrays;
PFNGLENABLEPROC glEnable;
@@ -105,13 +105,13 @@ struct GLHookSet
PFNGLGETFLOATI_VPROC glGetFloati_v;
PFNGLGETINTEGER64I_VPROC glGetInteger64i_v;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
PFNGLBLENDCOLORPROC glBlendColor;
PFNGLBLENDFUNCIPROC glBlendFunci;
PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei;
PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei;
PFNGLCOLORMASKIPROC glColorMaski;
PFNGLDEPTHMASKPROC glDepthMask;
PFNGLDEPTHRANGEARRAYVPROC glDepthRangeArrayv;
PFNGLCREATESHADERPROC glCreateShader;
PFNGLDELETESHADERPROC glDeleteShader;
+8 -8
View File
@@ -33,13 +33,13 @@
#define DLLExportHooks() \
HookInit(glBindTexture); \
HookInit(glBlendFunc); \
HookInit(glBlendColor); \
HookInit(glClear); \
HookInit(glClearColor); \
HookInit(glClearDepth); \
HookInit(glColorMask); \
HookInit(glCullFace); \
HookInit(glDepthFunc); \
HookInit(glDepthMask); \
HookInit(glDisable); \
HookInit(glDrawArrays); \
HookInit(glEnable); \
@@ -116,13 +116,13 @@
HookExtension(PFNGLGETFLOATI_VPROC, glGetFloati_v); \
HookExtension(PFNGLGETINTEGER64I_VPROC, glGetInteger64i_v); \
HookExtension(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus); \
HookExtension(PFNGLBLENDCOLORPROC, glBlendColor); \
HookExtension(PFNGLBLENDFUNCIPROC, glBlendFunci); \
HookExtension(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate); \
HookExtension(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparatei); \
HookExtension(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate); \
HookExtension(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparatei); \
HookExtension(PFNGLCOLORMASKIPROC, glColorMaski); \
HookExtension(PFNGLDEPTHMASKPROC, glDepthMask); \
HookExtension(PFNGLDEPTHRANGEARRAYVPROC, glDepthRangeArrayv); \
HookExtension(PFNGLCREATESHADERPROC, glCreateShader); \
HookExtension(PFNGLDELETESHADERPROC, glDeleteShader); \
@@ -210,13 +210,13 @@
HookExtension(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); \
HookExtension(PFNGLBINDTEXTUREPROC, glBindTexture); \
HookExtension(PFNGLBLENDFUNCPROC, glBlendFunc); \
HookExtension(PFNGLBLENDCOLORPROC, glBlendColor); \
HookExtension(PFNGLCLEARPROC, glClear); \
HookExtension(PFNGLCLEARCOLORPROC, glClearColor); \
HookExtension(PFNGLCLEARDEPTHPROC, glClearDepth); \
HookExtension(PFNGLCOLORMASKPROC, glColorMask); \
HookExtension(PFNGLCULLFACEPROC, glCullFace); \
HookExtension(PFNGLDEPTHFUNCPROC, glDepthFunc); \
HookExtension(PFNGLDEPTHMASKPROC, glDepthMask); \
HookExtension(PFNGLDISABLEPROC, glDisable); \
HookExtension(PFNGLDRAWARRAYSPROC, glDrawArrays); \
HookExtension(PFNGLENABLEPROC, glEnable); \
@@ -272,13 +272,13 @@
#define DefineDLLExportHooks() \
HookWrapper2(void, glBindTexture, GLenum, target, GLuint, texture); \
HookWrapper2(void, glBlendFunc, GLenum, sfactor, GLenum, dfactor); \
HookWrapper4(void, glBlendColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \
HookWrapper1(void, glClear, GLbitfield, mask); \
HookWrapper4(void, glClearColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \
HookWrapper1(void, glClearDepth, GLdouble, depth); \
HookWrapper4(void, glColorMask, GLboolean, red, GLboolean, green, GLboolean, blue, GLboolean, alpha); \
HookWrapper1(void, glCullFace, GLenum, mode); \
HookWrapper1(void, glDepthFunc, GLenum, func); \
HookWrapper1(void, glDepthMask, GLboolean, flag); \
HookWrapper1(void, glDisable, GLenum, cap); \
HookWrapper3(void, glDrawArrays, GLenum, mode, GLint, first, GLsizei, count); \
HookWrapper1(void, glEnable, GLenum, cap); \
@@ -355,13 +355,13 @@
HookWrapper3(void, glGetFloati_v, GLenum, target, GLuint, index, GLfloat *, data); \
HookWrapper3(void, glGetInteger64i_v, GLenum, target, GLuint, index, GLint64 *, data); \
HookWrapper1(GLenum, glCheckFramebufferStatus, GLenum, target); \
HookWrapper4(void, glBlendColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \
HookWrapper3(void, glBlendFunci, GLuint, buf, GLenum, src, GLenum, dst); \
HookWrapper4(void, glBlendFuncSeparate, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, sfactorAlpha, GLenum, dfactorAlpha); \
HookWrapper5(void, glBlendFuncSeparatei, GLuint, buf, GLenum, srcRGB, GLenum, dstRGB, GLenum, srcAlpha, GLenum, dstAlpha); \
HookWrapper2(void, glBlendEquationSeparate, GLenum, modeRGB, GLenum, modeAlpha); \
HookWrapper3(void, glBlendEquationSeparatei, GLuint, buf, GLenum, modeRGB, GLenum, modeAlpha); \
HookWrapper5(void, glColorMaski, GLuint, index, GLboolean, r, GLboolean, g, GLboolean, b, GLboolean, a); \
HookWrapper1(void, glDepthMask, GLboolean, flag); \
HookWrapper3(void, glDepthRangeArrayv, GLuint, first, GLsizei, count, const GLdouble *, v); \
HookWrapper1(GLuint, glCreateShader, GLenum, type); \
HookWrapper1(void, glDeleteShader, GLuint, shader); \
@@ -435,9 +435,9 @@
HookWrapper3(void, glGetUniformfv, GLuint, program, GLint, location, GLfloat *, params); \
HookWrapper3(void, glGetUniformiv, GLuint, program, GLint, location, GLint *, params); \
HookWrapper4(void, glUniformMatrix4fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \
HookWrapper2(void, glUniform1f, GLint, location, GLfloat, value); \
HookWrapper2(void, glUniform1i, GLint, location, GLint, value); \
HookWrapper2(void, glUniform1ui, GLint, location, GLuint, value); \
HookWrapper2(void, glUniform1f, GLint, location, GLfloat, v0); \
HookWrapper2(void, glUniform1i, GLint, location, GLint, v0); \
HookWrapper2(void, glUniform1ui, GLint, location, GLuint, v0); \
HookWrapper3(void, glUniform1fv, GLint, location, GLsizei, count, const GLfloat *, value); \
HookWrapper3(void, glUniform1iv, GLint, location, GLsizei, count, const GLint *, value); \
HookWrapper3(void, glUniform1uiv, GLint, location, GLsizei, count, const GLuint *, value); \
+20 -1
View File
@@ -92,11 +92,30 @@ struct GLResourceRecord : public ResourceRecord
static const NullInitialiser NullResource = MakeNullResource;
GLResourceRecord(ResourceId id) :
ResourceRecord(id, true),
ResourceRecord(id, true),
datatype(eGL_UNKNOWN_ENUM)
{
}
enum MapStatus
{
Unmapped,
Mapped_Read,
Mapped_Read_Real,
Mapped_Write,
Mapped_Write_Real,
Mapped_Write_Alloc,
};
struct
{
GLintptr offset;
GLsizeiptr length;
GLbitfield access;
MapStatus status;
byte *ptr;
} Map;
// pointer into binding chunk where datatype enum lives for this resource
GLenum datatype;
};