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:
baldurk
2014-12-26 16:04:22 +00:00
parent cd53d97418
commit f73a7a4a0c
7 changed files with 66 additions and 15 deletions
+3
View File
@@ -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);
+1
View File
@@ -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");
+3 -3
View File
@@ -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);
}
+10 -5
View File
@@ -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;
+11 -3
View File
@@ -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;