mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-11 17:20:56 +00:00
Support ARB_map_buffer_alignment on 64byte boundaries
* The real implementation can do more if it wants, and align to a larger alignment, but we just return 64 to the program and align to that, which satisfies the extension minimum requirements (and chances are no program takes advantage of wider alignment anyway).
This commit is contained in:
@@ -82,6 +82,9 @@ inline T AlignUp4(T x) { return (x+0x3) & (~0x3); }
|
||||
template<typename T>
|
||||
inline T AlignUp16(T x) { return (x+0xf) & (~0xf); }
|
||||
|
||||
template<typename T>
|
||||
inline T AlignUp(T x, T a) { return (x+(a-1)) & (~(a-1)); }
|
||||
|
||||
#define MAKE_FOURCC(a, b, c, d) (((uint32_t)(d) << 24) | ((uint32_t)(c) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(a))
|
||||
|
||||
bool FindDiffRange(void *a, void *b, size_t bufSize, size_t &diffStart, size_t &diffEnd);
|
||||
|
||||
@@ -387,6 +387,7 @@ WrappedOpenGL::WrappedOpenGL(const char *logfile, const GLHookSet &funcs)
|
||||
globalExts.push_back("GL_ARB_internalformat_query");
|
||||
globalExts.push_back("GL_ARB_internalformat_query2");
|
||||
globalExts.push_back("GL_ARB_invalidate_subdata");
|
||||
globalExts.push_back("GL_ARB_map_buffer_alignment");
|
||||
globalExts.push_back("GL_ARB_map_buffer_range");
|
||||
globalExts.push_back("GL_ARB_multi_bind");
|
||||
globalExts.push_back("GL_ARB_multi_draw_indirect");
|
||||
|
||||
@@ -180,12 +180,12 @@ struct GLResourceRecord : public ResourceRecord
|
||||
|
||||
GLResource Resource;
|
||||
|
||||
void AllocShadowStorage(size_t size)
|
||||
void AllocShadowStorage(size_t size, size_t alignment = 16)
|
||||
{
|
||||
if(ShadowPtr[0] == NULL)
|
||||
{
|
||||
ShadowPtr[0] = Serialiser::AllocAlignedBuffer(size);
|
||||
ShadowPtr[1] = Serialiser::AllocAlignedBuffer(size);
|
||||
ShadowPtr[0] = Serialiser::AllocAlignedBuffer(size, alignment);
|
||||
ShadowPtr[1] = Serialiser::AllocAlignedBuffer(size, alignment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -294,6 +294,9 @@ void WrappedOpenGL::glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, cons
|
||||
SCOPED_SERIALISE_CONTEXT(BUFFERSTORAGE);
|
||||
Serialise_glNamedBufferStorageEXT(buffer, size, data, flags);
|
||||
|
||||
// for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT
|
||||
scope.SetAlignment(64);
|
||||
|
||||
Chunk *chunk = scope.Get();
|
||||
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
@@ -324,6 +327,9 @@ void WrappedOpenGL::glBufferStorage(GLenum target, GLsizeiptr size, const void *
|
||||
Serialise_glNamedBufferStorageEXT(record->Resource.name,
|
||||
size, data, flags);
|
||||
|
||||
// for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT
|
||||
scope.SetAlignment(64);
|
||||
|
||||
Chunk *chunk = scope.Get();
|
||||
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
@@ -455,6 +461,9 @@ void WrappedOpenGL::glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const v
|
||||
SCOPED_SERIALISE_CONTEXT(BUFFERDATA);
|
||||
Serialise_glNamedBufferDataEXT(buffer, size, data, usage);
|
||||
|
||||
// for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT
|
||||
scope.SetAlignment(64);
|
||||
|
||||
Chunk *chunk = scope.Get();
|
||||
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
@@ -552,6 +561,9 @@ void WrappedOpenGL::glBufferData(GLenum target, GLsizeiptr size, const void *dat
|
||||
SCOPED_SERIALISE_CONTEXT(BUFFERDATA);
|
||||
Serialise_glNamedBufferDataEXT(buffer, size, data, usage);
|
||||
|
||||
// for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT
|
||||
scope.SetAlignment(64);
|
||||
|
||||
Chunk *chunk = scope.Get();
|
||||
|
||||
if(m_State == WRITING_CAPFRAME)
|
||||
@@ -1301,7 +1313,7 @@ void *WrappedOpenGL::glMapNamedBufferEXT(GLuint buffer, GLenum access)
|
||||
|
||||
if(shadow == NULL)
|
||||
{
|
||||
record->AllocShadowStorage(length);
|
||||
record->AllocShadowStorage(length, 64);
|
||||
shadow = (byte *)record->GetShadowPtr(0);
|
||||
|
||||
if(GetResourceManager()->IsResourceDirty(record->GetResourceID()))
|
||||
@@ -1397,8 +1409,6 @@ void *WrappedOpenGL::glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GL
|
||||
return record->Map.ptr;
|
||||
}
|
||||
|
||||
// TODO align return pointer to GL_MIN_MAP_BUFFER_ALIGNMENT (min 64)
|
||||
|
||||
if((access & GL_MAP_READ_BIT) != 0)
|
||||
{
|
||||
byte *ptr = record->GetDataPtr();
|
||||
@@ -1455,7 +1465,7 @@ void *WrappedOpenGL::glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GL
|
||||
GLint buflength;
|
||||
m_Real.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, &buflength);
|
||||
|
||||
record->AllocShadowStorage(buflength);
|
||||
record->AllocShadowStorage(buflength, 64);
|
||||
shadow = (byte *)record->GetShadowPtr(0);
|
||||
|
||||
if(!invalidateMap)
|
||||
|
||||
@@ -145,6 +145,12 @@ void WrappedOpenGL::glGetPointerv(GLenum pname, void **params)
|
||||
|
||||
void WrappedOpenGL::glGetIntegerv(GLenum pname, GLint *params)
|
||||
{
|
||||
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
|
||||
{
|
||||
if(params)
|
||||
*params = (GLint)64;
|
||||
return;
|
||||
}
|
||||
if(pname == eGL_NUM_EXTENSIONS)
|
||||
{
|
||||
if(params)
|
||||
@@ -162,6 +168,12 @@ void WrappedOpenGL::glGetBooleanv(GLenum pname, GLboolean *data)
|
||||
|
||||
void WrappedOpenGL::glGetInteger64v(GLenum pname, GLint64 *data)
|
||||
{
|
||||
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
|
||||
{
|
||||
if(data)
|
||||
*data = (GLint)64;
|
||||
return;
|
||||
}
|
||||
m_Real.glGetInteger64v(pname, data);
|
||||
}
|
||||
|
||||
@@ -172,6 +184,12 @@ void WrappedOpenGL::glGetBooleani_v(GLenum pname, GLuint index, GLboolean *data)
|
||||
|
||||
void WrappedOpenGL::glGetIntegeri_v(GLenum pname, GLuint index, GLint *data)
|
||||
{
|
||||
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
|
||||
{
|
||||
if(data)
|
||||
*data = (GLint)64;
|
||||
return;
|
||||
}
|
||||
m_Real.glGetIntegeri_v(pname, index, data);
|
||||
}
|
||||
|
||||
@@ -187,6 +205,12 @@ void WrappedOpenGL::glGetDoublei_v(GLenum pname, GLuint index, GLdouble *data)
|
||||
|
||||
void WrappedOpenGL::glGetInteger64i_v(GLenum pname, GLuint index, GLint64 *data)
|
||||
{
|
||||
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
|
||||
{
|
||||
if(data)
|
||||
*data = (GLint)64;
|
||||
return;
|
||||
}
|
||||
m_Real.glGetInteger64i_v(pname, index, data);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ int64_t Chunk::m_MaxChunks = 0;
|
||||
const uint32_t Serialiser::MAGIC_HEADER = MAKE_FOURCC('R', 'D', 'O', 'C');
|
||||
const size_t Serialiser::BufferAlignment = 16;
|
||||
|
||||
Chunk::Chunk(Serialiser *ser, uint32_t chunkType, bool temporary)
|
||||
Chunk::Chunk(Serialiser *ser, uint32_t chunkType, size_t alignment, bool temporary)
|
||||
{
|
||||
m_Length = (uint32_t)ser->GetOffset();
|
||||
|
||||
@@ -50,7 +50,12 @@ Chunk::Chunk(Serialiser *ser, uint32_t chunkType, bool temporary)
|
||||
|
||||
m_Temporary = temporary;
|
||||
|
||||
if(ser->HasAlignedData())
|
||||
if(alignment)
|
||||
{
|
||||
m_Data = Serialiser::AllocAlignedBuffer(m_Length, alignment);
|
||||
m_AlignedData = true;
|
||||
}
|
||||
else if(ser->HasAlignedData())
|
||||
{
|
||||
m_Data = Serialiser::AllocAlignedBuffer(m_Length);
|
||||
m_AlignedData = true;
|
||||
@@ -331,7 +336,7 @@ void Serialiser::ReadFromFile(uint64_t destOffs, size_t chunkLen)
|
||||
FileIO::fread(m_Buffer + destOffs - m_ReadOffset, 1, chunkLen, m_ReadFileHandle);
|
||||
}
|
||||
|
||||
byte *Serialiser::AllocAlignedBuffer(size_t size)
|
||||
byte *Serialiser::AllocAlignedBuffer(size_t size, size_t alignment)
|
||||
{
|
||||
byte *rawAlloc = NULL;
|
||||
|
||||
@@ -339,7 +344,7 @@ byte *Serialiser::AllocAlignedBuffer(size_t size)
|
||||
try
|
||||
#endif
|
||||
{
|
||||
rawAlloc = new byte[size+sizeof(byte*)+16];
|
||||
rawAlloc = new byte[size+sizeof(byte*)+alignment];
|
||||
}
|
||||
#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
|
||||
catch(std::bad_alloc&)
|
||||
@@ -353,7 +358,7 @@ byte *Serialiser::AllocAlignedBuffer(size_t size)
|
||||
|
||||
RDCASSERT(rawAlloc);
|
||||
|
||||
byte *alignedAlloc = (byte *)AlignUp16((size_t)(rawAlloc+sizeof(byte*)));
|
||||
byte *alignedAlloc = (byte *)AlignUp((size_t)(rawAlloc+sizeof(byte*)), alignment);
|
||||
|
||||
byte **realPointer = (byte **)alignedAlloc;
|
||||
realPointer[-1] = rawAlloc;
|
||||
|
||||
@@ -105,7 +105,7 @@ class Chunk
|
||||
#endif
|
||||
|
||||
// grab current contents of the serialiser into this chunk
|
||||
Chunk(Serialiser *ser, uint32_t chunkType, bool temp);
|
||||
Chunk(Serialiser *ser, uint32_t chunkType, size_t alignment, bool temp);
|
||||
|
||||
private:
|
||||
// no copy semantics
|
||||
@@ -505,7 +505,7 @@ class Serialiser
|
||||
// prints to the debug output log
|
||||
void DebugPrint(const char *fmt, ...);
|
||||
|
||||
static byte *AllocAlignedBuffer(size_t size);
|
||||
static byte *AllocAlignedBuffer(size_t size, size_t align = 16);
|
||||
static void FreeAlignedBuffer(byte *buf);
|
||||
|
||||
uint64_t FlushToDisk();
|
||||
@@ -753,6 +753,7 @@ class ScopedContext
|
||||
, m_DebugSer(debugser)
|
||||
#endif
|
||||
{
|
||||
m_Alignment = 0;
|
||||
m_Name = string(n) + " = " + t;
|
||||
m_Ser->PushContext(m_Name.c_str(), m_Idx, smallChunk);
|
||||
|
||||
@@ -770,6 +771,7 @@ class ScopedContext
|
||||
, m_DebugSer(debugser)
|
||||
#endif
|
||||
{
|
||||
m_Alignment = 0;
|
||||
m_Name = n;
|
||||
m_Ser->PushContext(m_Name.c_str(), m_Idx, smallChunk);
|
||||
|
||||
@@ -787,14 +789,20 @@ class ScopedContext
|
||||
End();
|
||||
}
|
||||
|
||||
void SetAlignment(size_t align)
|
||||
{
|
||||
m_Alignment = align;
|
||||
}
|
||||
|
||||
Chunk *Get(bool temporary = false)
|
||||
{
|
||||
End();
|
||||
return new Chunk(m_Ser, m_Idx, temporary);
|
||||
return new Chunk(m_Ser, m_Idx, m_Alignment, temporary);
|
||||
}
|
||||
private:
|
||||
std::string m_Name;
|
||||
uint32_t m_Idx;
|
||||
size_t m_Alignment;
|
||||
Serialiser *m_Ser;
|
||||
#ifdef DEBUG_TEXT_SERIALISER
|
||||
Serialiser *m_DebugSer;
|
||||
|
||||
Reference in New Issue
Block a user