   Loading resources in a separate thread problems on some card
  Hi,I'm trying to achieve asynchronous resource loading, i.e. textures, etc. are loaded in a separate thread (Loader) and all the rendering is done in the main thread (Renderer). The target platform is Windows XP or higher.I've seen many threads about this on this forum and I've successfully implemented it on my development station (GF 8500GT), however some problems arose when I tried to run it on other configurations.To start with, here is the basic flow of the application:1. Create context for Renderer.2. Create context for Loader.3. Call wglShareLists for these contexts.4. Start the Loader thread.4.a. In Loader thread: call wglMakeCurrent for the Loader context4.b. In Renderer thread: wait for 4.a to finish [1] then call wglMakeCurrent for the Renderer context.5.a. Loader waits for requests - if one shows up e.g. to load a texture - it loads it from the file, sends to GPU and flushes [2].5.b. Renderer renders - frame by frame :).Although it looks like working on my GF 8500GT, after running it on an oldie Riva TNT2, it appears not to flush (?) the last texture. I mean, if I request to load two textures - only the first one gets loaded, however when I load a third texture - the third one then appears to be not loaded, but the second one looks ok.Do you have any thoughts, how to solve this problem on Riva?Is the flow OK?What is your opinion on the [1] and [2] issues, is this normal?[1] - It turned out to be necessary to start the thread AND set its context BEFORE the main thread sets its own context. Never really read about this anywhere, but it's the only way I found to make it work on Radeon X1250. Otherwise (only if Loader sets its context after main thread) the back buffer gets messed up totally.[2] - It turned out to be necessary to call glFlush after glTexImage2D, setting filtering, etc., otherwise the texture would appear not fully loaded on my dev station (i.e. 60-90% filled with the proper data and the rest random garbage).If you're still not fed up reading, here is one semi-related, but solved story.When I started developing this system I've ran into big (as it seemed to me) problem on my GF 8500 - looked like nothing never got loaded. I spent two days looking for the reason and then my friend told me - try to drag this window to the other screen (as I'm running two monitor configuration, and the other screen would be the primary one). "D'oh", I thought, it started to work. Later I updated the GPU drivers and now it works on both screen ;).   
  > Is the flow OK?Depending on what your loader worker thread does (e.g. whether it also decompressed the texture from some storage format like JPG) it may be a loading time improvement if you had 3rd thread - "file loader" with its queue of files to load.So, the process would go like this (all asynchronous):(1) the main thread requests texture from loading thread(2) loading thread requests disc file to be loaded from "file loader"(3) "file loader" loads the file(4) loader decompresses texture from memory and creates textureThe reason why this can be better is that loading from disc is the real bottleneck when loading resources from HDD. So, instead of:Thread 1: load A, decompress A, load B, decompress Byou can:Thread 1: load A, load BThread 2:    decompress A, decomppress B   ;Quote:Original post by MickeyMouseit may be a loading time improvement if you had 3rd threadTBH, I don't care that much about performance yet. My biggest concern now is the fact it is not working on some configurations :(.   ;  Are you using the same pixelformat on both contexts?   ;  > Are you using the same pixelformat on both contexts?AFAIK pixel format is set for device context. I create two rendering contexts out of the same (one and only one) device context. So probably the answer is: yes. :)   ;I'm not sure how OpenGL handles this, but accessing graphics resources from another thread is quite tricky to get right in DirectX, which I assume is similar to OpenGL in this regard. You could set DirectX up to allow cross thread access, but in general it's safer, more straightforward and sometimes even faster to stick with a single thread accessing any graphics resources.You may still benefit from a seperate loader thread to do disk access and uncompression of image data though. Just have it prepare a byte chunk of ready-to-go texture data which the render/graphics thread can upload on the go. I realize this reply is probably not quite what you're looking for, but I thought I'd share my less fortunate experience [smile];  I wouldn't recommend using wglMakeCurrent at all. It seems agreed all across that its best to load resources in another thread, then, once they are ready, upload them to GL in the render thread.   ;  The way I implement this is I have a Render thread, that has a list of objects to render. If an object (model/texture/etc) isn't loaded, but is in the list then a worker process goes about doing what it needs to do and an appropriate proxy is used for rendering in the mean time.All the worker process does is load the resource from the HDD, decompress it (if required), and allocate the required resources etc. It then sets a flag against the resource to say it's loaded, but not uploaded to GL.The render thread then gets to this object, knows it's loaded in memory and ready, and goes about uploading to GL.This way only 1 thread actually ever 'talks' to GL. Avoiding a large array of problems.Hope this helps.   