@@ -182,67 +182,7 @@ void GLResourceManager::ContextPrepare_InitialState(GLResource res)
182182{
183183 GLInitialContents initContents;
184184
185- ResourceId id = GetID (res);
186-
187- if (res.Namespace == eResBuffer)
188- {
189- // get the length of the buffer
190- uint32_t length = 4 ;
191- GL.glGetNamedBufferParameterivEXT (res.name , eGL_BUFFER_SIZE, (GLint *)&length);
192-
193- // save old bindings
194- GLuint oldbuf1 = 0 , oldbuf2 = 0 ;
195- GL.glGetIntegerv (eGL_COPY_READ_BUFFER_BINDING, (GLint *)&oldbuf1);
196- GL.glGetIntegerv (eGL_COPY_WRITE_BUFFER_BINDING, (GLint *)&oldbuf2);
197-
198- // create a new buffer big enough to hold the contents
199- GLuint buf = 0 ;
200- GL.glGenBuffers (1 , &buf);
201- GL.glBindBuffer (eGL_COPY_WRITE_BUFFER, buf);
202- GL.glNamedBufferDataEXT (buf, (GLsizeiptr)RDCMAX (length, 4U ), NULL , eGL_STATIC_READ);
203-
204- // bind the live buffer for copying
205- GL.glBindBuffer (eGL_COPY_READ_BUFFER, res.name );
206-
207- // do the actual copy
208- if (length > 0 )
209- GL.glCopyBufferSubData (eGL_COPY_READ_BUFFER, eGL_COPY_WRITE_BUFFER, 0 , 0 , (GLsizeiptr)length);
210-
211- // workaround for some drivers - mapping/unmapping here seems to help avoid problems mapping
212- // later.
213- GL.glMapNamedBufferEXT (buf, eGL_READ_ONLY);
214- GL.glUnmapNamedBufferEXT (buf);
215-
216- // restore old bindings
217- GL.glBindBuffer (eGL_COPY_READ_BUFFER, oldbuf1);
218- GL.glBindBuffer (eGL_COPY_WRITE_BUFFER, oldbuf2);
219-
220- initContents.resource = GLResource (res.ContextShareGroup , eResBuffer, buf);
221- initContents.bufferLength = length;
222- }
223- else if (res.Namespace == eResProgram)
224- {
225- WriteSerialiser ser (new StreamWriter (4 * 1024 ), Ownership::Stream);
226-
227- ser.SetChunkMetadataRecording (m_Driver->GetSerialiser ().GetChunkMetadataRecording ());
228-
229- SCOPED_SERIALISE_CHUNK (SystemChunk::InitialContents);
230-
231- SERIALISE_ELEMENT (id).TypedAs (" GLResource" );
232- SERIALISE_ELEMENT (res.Namespace );
233-
234- SerialiseProgramBindings (ser, CaptureState::ActiveCapturing, res.name );
235- SerialiseProgramUniforms (ser, CaptureState::ActiveCapturing, res.name , NULL );
236-
237- SetInitialChunk (id, scope.Get ());
238- return ;
239- }
240- else if (res.Namespace == eResTexture)
241- {
242- PrepareTextureInitialContents (id, id, res);
243- return ;
244- }
245- else if (res.Namespace == eResFramebuffer)
185+ if (res.Namespace == eResFramebuffer)
246186 {
247187 FramebufferInitialData &data = initContents.fbo ;
248188
@@ -512,43 +452,160 @@ void GLResourceManager::ContextPrepare_InitialState(GLResource res)
512452
513453 GL.glBindVertexArray (prevVAO);
514454 }
515- else if (res.Namespace == eResRenderbuffer)
516- {
517- //
518- }
519- else
520- {
521- RDCERR (" Unexpected type of resource requiring initial state" );
522- }
523455
524- SetInitialContents (id , initContents);
456+ SetInitialContents (GetID (res) , initContents);
525457}
526458
527459bool GLResourceManager::Prepare_InitialState (GLResource res)
528460{
529- // We need to fetch the data for this resource on the right context.
530- // It's not safe for us to go changing contexts ourselves (the context could be active on
531- // another thread), so instead we'll queue this up to fetch when we are on a correct context.
532- // The correct context depends on whether the object is shared or not - if it's shared, any
533- // context in the same share group will do, otherwise it must be precisely the right context
534- //
535- // Because we've already allocated and set the blob above, it can be filled in any time
536- // before serialising (end of the frame, and if the context is never used before the end of
537- // the frame the resource can't be used, so not fetching the initial state doesn't matter).
538- //
539- // Note we also need to detect the case where the context is already current on another thread
540- // and we just start getting commands there, but that case already isn't supported as we don't
541- // detect it and insert state-change chunks, we assume all commands will come from a single
542- // thread.
543- ContextPair &ctx = m_Driver->GetCtx ();
544- if (res.ContextShareGroup == ctx.ctx || res.ContextShareGroup == ctx.shareGroup )
461+ // this function needs to be refactored to better deal with multiple
462+ // contexts and resources that are specific to a particular context
463+
464+ ResourceId Id = GetID (res);
465+
466+ if (res.Namespace == eResBuffer)
545467 {
546- // call immediately, we are on the right context or share group
547- ContextPrepare_InitialState (res);
468+ // get the length of the buffer
469+ uint32_t length = 4 ;
470+ GL.glGetNamedBufferParameterivEXT (res.name , eGL_BUFFER_SIZE, (GLint *)&length);
471+
472+ // save old bindings
473+ GLuint oldbuf1 = 0 , oldbuf2 = 0 ;
474+ GL.glGetIntegerv (eGL_COPY_READ_BUFFER_BINDING, (GLint *)&oldbuf1);
475+ GL.glGetIntegerv (eGL_COPY_WRITE_BUFFER_BINDING, (GLint *)&oldbuf2);
476+
477+ // create a new buffer big enough to hold the contents
478+ GLuint buf = 0 ;
479+ GL.glGenBuffers (1 , &buf);
480+ GL.glBindBuffer (eGL_COPY_WRITE_BUFFER, buf);
481+ GL.glNamedBufferDataEXT (buf, (GLsizeiptr)RDCMAX (length, 4U ), NULL , eGL_STATIC_READ);
482+
483+ // bind the live buffer for copying
484+ GL.glBindBuffer (eGL_COPY_READ_BUFFER, res.name );
485+
486+ // do the actual copy
487+ if (length > 0 )
488+ GL.glCopyBufferSubData (eGL_COPY_READ_BUFFER, eGL_COPY_WRITE_BUFFER, 0 , 0 , (GLsizeiptr)length);
489+
490+ // restore old bindings
491+ GL.glBindBuffer (eGL_COPY_READ_BUFFER, oldbuf1);
492+ GL.glBindBuffer (eGL_COPY_WRITE_BUFFER, oldbuf2);
493+
494+ SetInitialContents (
495+ Id, GLInitialContents (GLResource (res.ContextShareGroup , eResBuffer, buf), length));
496+ }
497+ else if (res.Namespace == eResProgram)
498+ {
499+ WriteSerialiser ser (new StreamWriter (4 * 1024 ), Ownership::Stream);
500+
501+ ser.SetChunkMetadataRecording (m_Driver->GetSerialiser ().GetChunkMetadataRecording ());
502+
503+ SCOPED_SERIALISE_CHUNK (SystemChunk::InitialContents);
504+
505+ SERIALISE_ELEMENT (Id).TypedAs (" GLResource" );
506+ SERIALISE_ELEMENT (res.Namespace );
507+
508+ SerialiseProgramBindings (ser, CaptureState::ActiveCapturing, res.name );
509+ SerialiseProgramUniforms (ser, CaptureState::ActiveCapturing, res.name , NULL );
510+
511+ SetInitialChunk (Id, scope.Get ());
512+ }
513+ else if (res.Namespace == eResTexture)
514+ {
515+ PrepareTextureInitialContents (Id, Id, res);
516+ }
517+ else if (res.Namespace == eResFramebuffer)
518+ {
519+ // We need to fetch the data for this FBO on the right context.
520+ // It's not safe for us to go changing contexts ourselves (the context could be active on
521+ // another thread), so instead we'll queue this up to fetch when we are on a correct context.
522+ // The correct context depends on whether the object is shared or not - if it's shared, any
523+ // context in the same share group will do, otherwise it must be precisely the right context
524+ //
525+ // Because we've already allocated and set the blob above, it can be filled in any time
526+ // before serialising (end of the frame, and if the context is never used before the end of
527+ // the frame the resource can't be used, so not fetching the initial state doesn't matter).
528+ //
529+ // Note we also need to detect the case where the context is already current on another thread
530+ // and we just start getting commands there, but that case already isn't supported as we don't
531+ // detect it and insert state-change chunks, we assume all commands will come from a single
532+ // thread.
533+ ContextPair &ctx = m_Driver->GetCtx ();
534+ if (res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup )
535+ {
536+ m_Driver->QueuePrepareInitialState (res);
537+ }
538+ else
539+ {
540+ // call immediately, we are on the right context or for one reason or another the context
541+ // doesn't matter for fetching this resource (res.Context is NULL or vendorcheck means they're
542+ // shared).
543+ ContextPrepare_InitialState (res);
544+ }
545+ }
546+ else if (res.Namespace == eResProgramPipe)
547+ {
548+ // queue initial state fetching if we're not on the right context, see above in FBOs for more
549+ // explanation of this.
550+ ContextPair &ctx = m_Driver->GetCtx ();
551+ if (res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup )
552+ {
553+ m_Driver->QueuePrepareInitialState (res);
554+ }
555+ else
556+ {
557+ ContextPrepare_InitialState (res);
558+ }
559+ }
560+ else if (res.Namespace == eResSampler)
561+ {
562+ // queue initial state fetching if we're not on the right context, see above in FBOs for more
563+ // explanation of this.
564+ ContextPair &ctx = m_Driver->GetCtx ();
565+ if (res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup )
566+ {
567+ m_Driver->QueuePrepareInitialState (res);
568+ }
569+ else
570+ {
571+ ContextPrepare_InitialState (res);
572+ }
573+ }
574+ else if (res.Namespace == eResFeedback)
575+ {
576+ // queue initial state fetching if we're not on the right context, see above in FBOs for more
577+ // explanation of this.
578+ ContextPair &ctx = m_Driver->GetCtx ();
579+ if (res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup )
580+ {
581+ m_Driver->QueuePrepareInitialState (res);
582+ }
583+ else
584+ {
585+ ContextPrepare_InitialState (res);
586+ }
587+ }
588+ else if (res.Namespace == eResVertexArray)
589+ {
590+ // queue initial state fetching if we're not on the right context, see above in FBOs for more
591+ // explanation of this.
592+ ContextPair &ctx = m_Driver->GetCtx ();
593+ if (res.ContextShareGroup != ctx.ctx && res.ContextShareGroup != ctx.shareGroup )
594+ {
595+ m_Driver->QueuePrepareInitialState (res);
596+ }
597+ else
598+ {
599+ ContextPrepare_InitialState (res);
600+ }
601+ }
602+ else if (res.Namespace == eResRenderbuffer)
603+ {
604+ //
548605 }
549606 else
550607 {
551- m_Driver-> QueuePrepareInitialState (res );
608+ RDCERR ( " Unexpected type of resource requiring initial state " );
552609 }
553610
554611 return true ;
0 commit comments