If you run a texture transfer call on `GL.TexImage2D` or `Gl.TexSubImage2D`, you'll get a performance warning stating: > Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering This means that rendering is delayed until the pixel transfer (texture transfer) completes, meaning that even if you used PBO correctly, it's not truly asynchronous. To perform a proper asynchronous transfer, you need to use another OpenGL context. The window that your game is displayed in uses your main rendering OpenGL context, where all your resources live. But OpenGL allows some resources - like textures - to be shared across OpenGL contexts. VE automatically creates the background OpenGL context for you. It runs on another thread, 's invisible and doesn't display a window, but can perform texture transfers. To perform a texture transfer on this context, you'll need to pass a `Func` like so: ```cs FenceObject fence; BackgroundOpenGLWindow.TextureTransferActions.Add((GL GL2) => { // Perform a texture transfer GL2.TexSubImage2D(...); fence = new FenceObject(); fence.OnRender(GL2); return fence; }); ``` Note that this uses a separate GL variable called `GL2`, instead of the regular `Gl`. This ensures it runs the commands on the background GL context. This function must return a [[FenceObject]], to keep track of when the transfer is complete. You can then check this fence on the main thread: ```cs if (fence.signaled) { // The transfer is complete - render the texure! } ```