mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-27 20:31:02 +00:00
Save off and store VAO initial frame state
This commit is contained in:
@@ -360,6 +360,8 @@ WrappedOpenGL::WrappedOpenGL(const wchar_t *logfile, const GLHookSet &funcs)
|
||||
m_FakeBB_FBO = 0;
|
||||
m_FakeBB_Color = 0;
|
||||
m_FakeBB_DepthStencil = 0;
|
||||
|
||||
GetResourceManager()->SetSerialiser(m_State, m_pSerialiser);
|
||||
|
||||
RDCDEBUG("Debug Text enabled - for development! remove before release!");
|
||||
m_pSerialiser->SetDebugText(true);
|
||||
@@ -1401,7 +1403,7 @@ void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context)
|
||||
default:
|
||||
// ignore system chunks
|
||||
if((int)context == (int)INITIAL_CONTENTS)
|
||||
RDCERR("Initial contents not implemented yet");
|
||||
GetResourceManager()->Serialise_InitialState(GLResource(MakeNullResource));
|
||||
else if((int)context < (int)FIRST_CHUNK_ID)
|
||||
m_pSerialiser->SkipCurrentChunk();
|
||||
else
|
||||
|
||||
@@ -26,6 +26,21 @@
|
||||
#include "driver/gl/gl_manager.h"
|
||||
#include "driver/gl/gl_driver.h"
|
||||
|
||||
struct VertexArrayInitialData
|
||||
{
|
||||
VertexArrayInitialData()
|
||||
{
|
||||
RDCEraseEl(*this);
|
||||
}
|
||||
uint32_t enabled;
|
||||
uint32_t vbslot;
|
||||
uint32_t offset;
|
||||
GLenum type;
|
||||
int32_t normalized;
|
||||
uint32_t integer;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
bool GLResourceManager::SerialisableResource(ResourceId id, GLResourceRecord *record)
|
||||
{
|
||||
if(id == m_GL->GetContextResourceID())
|
||||
@@ -33,17 +48,160 @@ bool GLResourceManager::SerialisableResource(ResourceId id, GLResourceRecord *re
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLResourceManager::Need_InitialStateChunk(GLResource res)
|
||||
{
|
||||
return res.Namespace != eResBuffer;
|
||||
}
|
||||
|
||||
bool GLResourceManager::Prepare_InitialState(GLResource res)
|
||||
{
|
||||
ResourceId Id = GetID(res);
|
||||
|
||||
if(res.Namespace == eResBuffer)
|
||||
{
|
||||
GLResourceRecord *record = GetResourceRecord(res);
|
||||
|
||||
// TODO copy this to an immutable buffer elsewhere and SetInitialContents() it.
|
||||
// then only do the readback in Serialise_InitialState
|
||||
|
||||
GLint length;
|
||||
m_GL->glGetNamedBufferParameterivEXT(res.name, eGL_BUFFER_SIZE, &length);
|
||||
|
||||
m_GL->glGetNamedBufferSubDataEXT(res.name, 0, length, record->GetDataPtr());
|
||||
}
|
||||
else if(res.Namespace == eResVertexArray)
|
||||
{
|
||||
GLuint VAO = 0;
|
||||
m_GL->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO);
|
||||
|
||||
m_GL->glBindVertexArray(res.name);
|
||||
|
||||
VertexArrayInitialData *data = (VertexArrayInitialData *)new byte[sizeof(VertexArrayInitialData)*16];
|
||||
|
||||
for(GLuint i=0; i < 16; i++)
|
||||
{
|
||||
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, (GLint *)&data[i].enabled);
|
||||
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, (GLint *)&data[i].vbslot);
|
||||
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, (GLint*)&data[i].offset);
|
||||
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&data[i].type);
|
||||
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, (GLint *)&data[i].normalized);
|
||||
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_INTEGER, (GLint *)&data[i].integer);
|
||||
m_GL->glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&data[i].size);
|
||||
}
|
||||
|
||||
SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, (byte *)data));
|
||||
|
||||
m_GL->glBindVertexArray(VAO);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected type of resource requiring initial state");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLResourceManager::Force_InitialState(GLResource res)
|
||||
{
|
||||
// hack for now, these should be tracked through the normal dirty/ref tracking process.
|
||||
if(res.Namespace == eResVertexArray) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLResourceManager::Serialise_InitialState(GLResource res)
|
||||
{
|
||||
ResourceId Id = ResourceId();
|
||||
|
||||
Serialiser *m_pSerialiser = NULL;
|
||||
LogState m_State = READING;
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
Id = GetID(res);
|
||||
|
||||
if(res.Namespace != eResBuffer)
|
||||
m_pSerialiser->Serialise("Id", Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSerialiser->Serialise("Id", Id);
|
||||
}
|
||||
|
||||
if(m_State < WRITING)
|
||||
{
|
||||
if(HasLiveResource(Id))
|
||||
res = GetLiveResource(Id);
|
||||
else
|
||||
res = GLResource(MakeNullResource);
|
||||
}
|
||||
|
||||
if(res.Namespace == eResVertexArray)
|
||||
{
|
||||
VertexArrayInitialData data[16];
|
||||
|
||||
if(m_State >= WRITING)
|
||||
{
|
||||
VertexArrayInitialData *initialdata = (VertexArrayInitialData *)GetInitialContents(Id).blob;
|
||||
memcpy(data, initialdata, sizeof(data));
|
||||
}
|
||||
|
||||
for(GLuint i=0; i < 16; i++)
|
||||
{
|
||||
m_pSerialiser->Serialise("data[].enabled", data[i].enabled);
|
||||
m_pSerialiser->Serialise("data[].vbslot", data[i].vbslot);
|
||||
m_pSerialiser->Serialise("data[].offset", data[i].offset);
|
||||
m_pSerialiser->Serialise("data[].type", data[i].type);
|
||||
m_pSerialiser->Serialise("data[].normalized", data[i].normalized);
|
||||
m_pSerialiser->Serialise("data[].integer", data[i].integer);
|
||||
m_pSerialiser->Serialise("data[].size", data[i].size);
|
||||
}
|
||||
|
||||
if(m_State < WRITING)
|
||||
{
|
||||
byte *blob = new byte[sizeof(data)];
|
||||
memcpy(blob, data, sizeof(data));
|
||||
|
||||
SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected type of resource requiring initial state");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLResourceManager::Create_InitialState(ResourceId id, GLResource live, bool hasData)
|
||||
{
|
||||
RDCUNIMPLEMENTED("Expect all initial states to be created & not skipped, presently");
|
||||
}
|
||||
|
||||
void GLResourceManager::Apply_InitialState(GLResource live, InitialContentData initial)
|
||||
{
|
||||
if(live.Namespace == eResVertexArray)
|
||||
{
|
||||
GLuint VAO = 0;
|
||||
m_GL->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO);
|
||||
|
||||
m_GL->glBindVertexArray(live.name);
|
||||
|
||||
VertexArrayInitialData *initialdata = (VertexArrayInitialData *)initial.blob;
|
||||
|
||||
for(GLuint i=0; i < 16; i++)
|
||||
{
|
||||
m_GL->glVertexAttribBinding(i, initialdata[i].vbslot);
|
||||
|
||||
if(initialdata[i].integer == 0)
|
||||
m_GL->glVertexAttribFormat(i, initialdata[i].size, initialdata[i].type, (GLboolean)initialdata[i].normalized, initialdata[i].offset);
|
||||
else
|
||||
m_GL->glVertexAttribIFormat(i, initialdata[i].size, initialdata[i].type, initialdata[i].offset);
|
||||
}
|
||||
|
||||
m_GL->glBindVertexArray(VAO);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected type of resource requiring initial state");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,11 @@ class WrappedOpenGL;
|
||||
class GLResourceManager : public ResourceManager<GLResource, GLResourceRecord>
|
||||
{
|
||||
public:
|
||||
GLResourceManager(WrappedOpenGL *gl) : m_GL(gl), m_SyncName(1) {}
|
||||
GLResourceManager(WrappedOpenGL *gl) : m_GL(gl), m_SyncName(1)
|
||||
{
|
||||
m_pSerialiser = NULL;
|
||||
m_State = READING;
|
||||
}
|
||||
~GLResourceManager() {}
|
||||
|
||||
void Shutdown()
|
||||
@@ -134,17 +138,24 @@ class GLResourceManager : public ResourceManager<GLResource, GLResourceRecord>
|
||||
return m_SyncIDs[sync];
|
||||
}
|
||||
|
||||
void SetSerialiser(LogState state, Serialiser *ser)
|
||||
{
|
||||
m_State = state;
|
||||
m_pSerialiser = ser;
|
||||
}
|
||||
|
||||
bool Serialise_InitialState(GLResource res);
|
||||
|
||||
private:
|
||||
bool SerialisableResource(ResourceId id, GLResourceRecord *record);
|
||||
|
||||
bool ResourceTypeRelease(GLResource res) { return true; }
|
||||
|
||||
bool Force_InitialState(GLResource res) { return false; }
|
||||
bool Need_InitialStateChunk(GLResource res) { return res.Namespace != eResBuffer; }
|
||||
bool Force_InitialState(GLResource res);
|
||||
bool Need_InitialStateChunk(GLResource res);
|
||||
bool Prepare_InitialState(GLResource res);
|
||||
bool Serialise_InitialState(GLResource res) { return true; }
|
||||
void Create_InitialState(ResourceId id, GLResource live, bool hasData) { }
|
||||
void Apply_InitialState(GLResource live, InitialContentData initial) { }
|
||||
void Create_InitialState(ResourceId id, GLResource live, bool hasData);
|
||||
void Apply_InitialState(GLResource live, InitialContentData initial);
|
||||
|
||||
map<GLResource, GLResourceRecord*> m_GLResourceRecords;
|
||||
|
||||
@@ -156,6 +167,9 @@ class GLResourceManager : public ResourceManager<GLResource, GLResourceRecord>
|
||||
map<GLuint, GLsync> m_CurrentSyncs;
|
||||
volatile int64_t m_SyncName;
|
||||
|
||||
Serialiser *m_pSerialiser;
|
||||
LogState m_State;
|
||||
|
||||
WrappedOpenGL *m_GL;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user