Handle glBufferData being used to rename/orphan to a new size

This commit is contained in:
baldurk
2014-12-03 13:57:03 +00:00
parent 34b39d79d2
commit 8397aa1f28
3 changed files with 69 additions and 5 deletions
+1 -3
View File
@@ -62,9 +62,7 @@ void ResourceRecord::Delete(ResourceRecordHandler *mgr)
}
}
for(auto it=m_Chunks.begin(); it != m_Chunks.end(); ++it)
SAFE_DELETE(it->second);
m_Chunks.clear();
DeleteChunks();
for(int i=0; i < NumSubResources; i++)
{
+9
View File
@@ -192,6 +192,15 @@ struct ResourceRecord
UnlockChunks();
}
void DeleteChunks()
{
LockChunks();
for(auto it=m_Chunks.begin(); it != m_Chunks.end(); ++it)
SAFE_DELETE(it->second);
m_Chunks.clear();
UnlockChunks();
}
Chunk *GetLastChunk() const
{
RDCASSERT(HasChunks());
@@ -348,6 +348,34 @@ void WrappedOpenGL::glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const v
memset(record->GetDataPtr(), 0xbe, (size_t)size);
return;
}
// if we're recreating the buffer, clear the record and add new chunks. Normally
// we would just mark this record as dirty and pick it up on the capture frame as initial
// data, but we don't support (if it's even possible) querying out size etc.
// we need to add only the chunks required - glGenBuffers, glBindBuffer to current target,
// and this buffer storage. All other chunks have no effect
if(m_State == WRITING_IDLE && record->GetDataPtr() != NULL || size != record->Length)
{
record->DeleteChunks();
// add glGenBuffers chunk
{
SCOPED_SERIALISE_CONTEXT(GEN_BUFFER);
Serialise_glGenBuffers(1, &buffer);
record->AddChunk(scope.Get());
}
// add glBindBuffer chunk
{
SCOPED_SERIALISE_CONTEXT(GEN_BUFFER);
Serialise_glBindBuffer(record->datatype, buffer);
record->AddChunk(scope.Get());
}
// we're about to add the buffer data chunk
}
SCOPED_SERIALISE_CONTEXT(BUFFERDATA);
Serialise_glNamedBufferDataEXT(buffer, size, data, usage);
@@ -389,9 +417,38 @@ void WrappedOpenGL::glBufferData(GLenum target, GLsizeiptr size, const void *dat
return;
}
GLuint buffer = GetResourceManager()->GetCurrentResource(record->GetResourceID()).name;
// if we're recreating the buffer, clear the record and add new chunks. Normally
// we would just mark this record as dirty and pick it up on the capture frame as initial
// data, but we don't support (if it's even possible) querying out size etc.
// we need to add only the chunks required - glGenBuffers, glBindBuffer to current target,
// and this buffer storage. All other chunks have no effect
if(m_State == WRITING_IDLE && record->GetDataPtr() != NULL || size != record->Length)
{
record->DeleteChunks();
// add glGenBuffers chunk
{
SCOPED_SERIALISE_CONTEXT(GEN_BUFFER);
Serialise_glGenBuffers(1, &buffer);
record->AddChunk(scope.Get());
}
// add glBindBuffer chunk
{
SCOPED_SERIALISE_CONTEXT(GEN_BUFFER);
Serialise_glBindBuffer(record->datatype, buffer);
record->AddChunk(scope.Get());
}
// we're about to add the buffer data chunk
}
SCOPED_SERIALISE_CONTEXT(BUFFERDATA);
Serialise_glNamedBufferDataEXT(GetResourceManager()->GetCurrentResource(record->GetResourceID()).name,
size, data, usage);
Serialise_glNamedBufferDataEXT(buffer, size, data, usage);
Chunk *chunk = scope.Get();