Revert "All initial states on GL must be queued"

* This reverts commit be231884b4 temporarily until
  it can be restored.
This commit is contained in:
baldurk
2019-04-29 10:45:53 +01:00
parent 115fcec8e5
commit 214d852285
+148 -91
View File
@@ -182,67 +182,7 @@ void GLResourceManager::ContextPrepare_InitialState(GLResource res)
{
GLInitialContents initContents;
ResourceId id = GetID(res);
if(res.Namespace == eResBuffer)
{
// get the length of the buffer
uint32_t length = 4;
GL.glGetNamedBufferParameterivEXT(res.name, eGL_BUFFER_SIZE, (GLint *)&length);
// save old bindings
GLuint oldbuf1 = 0, oldbuf2 = 0;
GL.glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint *)&oldbuf1);
GL.glGetIntegerv(eGL_COPY_WRITE_BUFFER_BINDING, (GLint *)&oldbuf2);
// create a new buffer big enough to hold the contents
GLuint buf = 0;
GL.glGenBuffers(1, &buf);
GL.glBindBuffer(eGL_COPY_WRITE_BUFFER, buf);
GL.glNamedBufferDataEXT(buf, (GLsizeiptr)RDCMAX(length, 4U), NULL, eGL_STATIC_READ);
// bind the live buffer for copying
GL.glBindBuffer(eGL_COPY_READ_BUFFER, res.name);
// do the actual copy
if(length > 0)
GL.glCopyBufferSubData(eGL_COPY_READ_BUFFER, eGL_COPY_WRITE_BUFFER, 0, 0, (GLsizeiptr)length);
// workaround for some drivers - mapping/unmapping here seems to help avoid problems mapping
// later.
GL.glMapNamedBufferEXT(buf, eGL_READ_ONLY);
GL.glUnmapNamedBufferEXT(buf);
// restore old bindings
GL.glBindBuffer(eGL_COPY_READ_BUFFER, oldbuf1);
GL.glBindBuffer(eGL_COPY_WRITE_BUFFER, oldbuf2);
initContents.resource = GLResource(res.ContextShareGroup, eResBuffer, buf);
initContents.bufferLength = length;
}
else if(res.Namespace == eResProgram)
{
WriteSerialiser ser(new StreamWriter(4 * 1024), Ownership::Stream);
ser.SetChunkMetadataRecording(m_Driver->GetSerialiser().GetChunkMetadataRecording());
SCOPED_SERIALISE_CHUNK(SystemChunk::InitialContents);
SERIALISE_ELEMENT(id).TypedAs("GLResource");
SERIALISE_ELEMENT(res.Namespace);
SerialiseProgramBindings(ser, CaptureState::ActiveCapturing, res.name);
SerialiseProgramUniforms(ser, CaptureState::ActiveCapturing, res.name, NULL);
SetInitialChunk(id, scope.Get());
return;
}
else if(res.Namespace == eResTexture)
{
PrepareTextureInitialContents(id, id, res);
return;
}
else if(res.Namespace == eResFramebuffer)
if(res.Namespace == eResFramebuffer)
{
FramebufferInitialData &data = initContents.fbo;
@@ -512,6 +452,153 @@ void GLResourceManager::ContextPrepare_InitialState(GLResource res)
GL.glBindVertexArray(prevVAO);
}
SetInitialContents(GetID(res), initContents);
}
bool GLResourceManager::Prepare_InitialState(GLResource res)
{
// this function needs to be refactored to better deal with multiple
// contexts and resources that are specific to a particular context
ResourceId Id = GetID(res);
if(res.Namespace == eResBuffer)
{
// get the length of the buffer
uint32_t length = 4;
GL.glGetNamedBufferParameterivEXT(res.name, eGL_BUFFER_SIZE, (GLint *)&length);
// save old bindings
GLuint oldbuf1 = 0, oldbuf2 = 0;
GL.glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint *)&oldbuf1);
GL.glGetIntegerv(eGL_COPY_WRITE_BUFFER_BINDING, (GLint *)&oldbuf2);
// create a new buffer big enough to hold the contents
GLuint buf = 0;
GL.glGenBuffers(1, &buf);
GL.glBindBuffer(eGL_COPY_WRITE_BUFFER, buf);
GL.glNamedBufferDataEXT(buf, (GLsizeiptr)RDCMAX(length, 4U), NULL, eGL_STATIC_READ);
// bind the live buffer for copying
GL.glBindBuffer(eGL_COPY_READ_BUFFER, res.name);
// do the actual copy
if(length > 0)
GL.glCopyBufferSubData(eGL_COPY_READ_BUFFER, eGL_COPY_WRITE_BUFFER, 0, 0, (GLsizeiptr)length);
// restore old bindings
GL.glBindBuffer(eGL_COPY_READ_BUFFER, oldbuf1);
GL.glBindBuffer(eGL_COPY_WRITE_BUFFER, oldbuf2);
SetInitialContents(
Id, GLInitialContents(GLResource(res.ContextShareGroup, eResBuffer, buf), length));
}
else if(res.Namespace == eResProgram)
{
WriteSerialiser ser(new StreamWriter(4 * 1024), Ownership::Stream);
ser.SetChunkMetadataRecording(m_Driver->GetSerialiser().GetChunkMetadataRecording());
SCOPED_SERIALISE_CHUNK(SystemChunk::InitialContents);
SERIALISE_ELEMENT(Id).TypedAs("GLResource");
SERIALISE_ELEMENT(res.Namespace);
SerialiseProgramBindings(ser, CaptureState::ActiveCapturing, res.name);
SerialiseProgramUniforms(ser, CaptureState::ActiveCapturing, res.name, NULL);
SetInitialChunk(Id, scope.Get());
}
else if(res.Namespace == eResTexture)
{
PrepareTextureInitialContents(Id, Id, res);
}
else if(res.Namespace == eResFramebuffer)
{
// We need to fetch the data for this FBO on the right context.
// It's not safe for us to go changing contexts ourselves (the context could be active on
// another thread), so instead we'll queue this up to fetch when we are on a correct context.
// The correct context depends on whether the object is shared or not - if it's shared, any
// context in the same share group will do, otherwise it must be precisely the right context
//
// Because we've already allocated and set the blob above, it can be filled in any time
// before serialising (end of the frame, and if the context is never used before the end of
// the frame the resource can't be used, so not fetching the initial state doesn't matter).
//
// Note we also need to detect the case where the context is already current on another thread
// and we just start getting commands there, but that case already isn't supported as we don't
// detect it and insert state-change chunks, we assume all commands will come from a single
// thread.
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup)
{
m_Driver->QueuePrepareInitialState(res);
}
else
{
// call immediately, we are on the right context or for one reason or another the context
// doesn't matter for fetching this resource (res.Context is NULL or vendorcheck means they're
// shared).
ContextPrepare_InitialState(res);
}
}
else if(res.Namespace == eResProgramPipe)
{
// queue initial state fetching if we're not on the right context, see above in FBOs for more
// explanation of this.
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup)
{
m_Driver->QueuePrepareInitialState(res);
}
else
{
ContextPrepare_InitialState(res);
}
}
else if(res.Namespace == eResSampler)
{
// queue initial state fetching if we're not on the right context, see above in FBOs for more
// explanation of this.
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup)
{
m_Driver->QueuePrepareInitialState(res);
}
else
{
ContextPrepare_InitialState(res);
}
}
else if(res.Namespace == eResFeedback)
{
// queue initial state fetching if we're not on the right context, see above in FBOs for more
// explanation of this.
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup)
{
m_Driver->QueuePrepareInitialState(res);
}
else
{
ContextPrepare_InitialState(res);
}
}
else if(res.Namespace == eResVertexArray)
{
// queue initial state fetching if we're not on the right context, see above in FBOs for more
// explanation of this.
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup)
{
m_Driver->QueuePrepareInitialState(res);
}
else
{
ContextPrepare_InitialState(res);
}
}
else if(res.Namespace == eResRenderbuffer)
{
//
@@ -521,36 +608,6 @@ void GLResourceManager::ContextPrepare_InitialState(GLResource res)
RDCERR("Unexpected type of resource requiring initial state");
}
SetInitialContents(id, initContents);
}
bool GLResourceManager::Prepare_InitialState(GLResource res)
{
// We need to fetch the data for this resource on the right context.
// It's not safe for us to go changing contexts ourselves (the context could be active on
// another thread), so instead we'll queue this up to fetch when we are on a correct context.
// The correct context depends on whether the object is shared or not - if it's shared, any
// context in the same share group will do, otherwise it must be precisely the right context
//
// Because we've already allocated and set the blob above, it can be filled in any time
// before serialising (end of the frame, and if the context is never used before the end of
// the frame the resource can't be used, so not fetching the initial state doesn't matter).
//
// Note we also need to detect the case where the context is already current on another thread
// and we just start getting commands there, but that case already isn't supported as we don't
// detect it and insert state-change chunks, we assume all commands will come from a single
// thread.
ContextPair &ctx = m_Driver->GetCtx();
if(res.ContextShareGroup == ctx.ctx || res.ContextShareGroup == ctx.shareGroup)
{
// call immediately, we are on the right context or share group
ContextPrepare_InitialState(res);
}
else
{
m_Driver->QueuePrepareInitialState(res);
}
return true;
}