mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-26 09:21:37 +00:00
First attempt to implement Map/Unmap
This commit is contained in:
@@ -177,6 +177,7 @@ enum GLChunkType
|
||||
BIND_BUFFER_BASE,
|
||||
BIND_BUFFER_RANGE,
|
||||
BUFFERDATA,
|
||||
UNMAP,
|
||||
GEN_VERTEXARRAY,
|
||||
BIND_VERTEXARRAY,
|
||||
VERTEXATTRIBPOINTER,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); \
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user