|
ShinAli posted:Not really a programming question, but I'd like to know what you know-more-than-I-dos think.
|
# ? Oct 27, 2011 20:42 |
|
|
# ? Jun 3, 2024 21:38 |
|
I've run into an OpenGL/OpenCL multithreading/resource sharing question. I have an app that uses multiple threads to poll a bunch of Kinects for depth/rgb frames. It then renders the frames into separate OpenGL contexts (right now there is a 1-1 correspondence between an image and an OpenGL context). To my understanding it is possible to get OpenGL contexts to share display lists and textures (I'm using Qt for the UI and it offers such functionality and bone stock OpenGL does it as well). However, I haven't found it explicitly stated anywhere that more than two contexts can share resources. Additionally, I plan to add some OpenCL functionality that basically does computation on these images and outputs results that I also want to be able to render in the aforementioned OpenGL contexts. Now, OpenCL allows you to interop with OpenGL by defining a single OpenGL context to share resources with. The overarching question is whether I can "chain" resource sharing between contexts. As in, when my application starts, create a single "parent" OpenGL context, then have ALL other OpenGL and OpenCL contexts (that may reside in other threads) actually share resources with that "parent" context and as an extension share resources with each other?
|
# ? Nov 1, 2011 23:22 |
|
Why are you using separate OpenGL contexts for everything?
|
# ? Nov 2, 2011 00:53 |
|
Paniolo posted:Why are you using separate OpenGL contexts for everything? I have different widget classes that handle visualizing different types of data and Qt makes no guarantee that they will share an OpenGL context.
|
# ? Nov 2, 2011 03:08 |
|
Paniolo posted:Why are you using separate OpenGL contexts for everything? If you are using multiple contexts you MUST use a separate context per thread. To answer the main question, yes, multiple contexts can share resources. Note that not everything is shared, like Fences (but Syncs are). Check the spec for specifics. If you are trying to do something like Context A, B, C are all shared Context B modifies a texture Context A and C get the change That should work. Create context A. Create contexts B and C as contexts shared with A. That should allow you to do this. Keep in mind you've now created a slew of race conditions, so watch your locks! Also, you have to make sure commands have been flushed to the GPU on the current context before expecting the results to show up elsewhere. For example: Context A calls glTexSubImage2D on Texture 1 Context B calls glBindTexture(1), Draw This will have undefined results. You must do the following: Context A calls glTexSubImage2D on Texture 1 Context A calls glFlush Context B calls glBindTexture(1), Draw On OSX, you must also call glBindTexture before changes are picked up, not sure about windows. It's probably vendor-specific. And again, you need a context per thread. Do not try to access the same context from separate threads; only pain and suffering awaits. You probably want to re-architect your design, as it doesn't sound very good to me. Also, can't Qt pass you an opaque pointer? You can't hold a single context there and lock around its use? Or have a single background thread doing the rendering? Spite fucked around with this message at 03:24 on Nov 3, 2011 |
# ? Nov 3, 2011 03:22 |
|
Spite posted:If you are using multiple contexts you MUST use a separate context per thread. That's what I ended up doing. I create context on application launch and then any other contexts that are initialized share resources with that one context. quote:Keep in mind you've now created a slew of race conditions, so watch your locks! quote:You probably want to re-architect your design, as it doesn't sound very good to me. Also, can't Qt pass you an opaque pointer? You can't hold a single context there and lock around its use? Or have a single background thread doing the rendering?
|
# ? Nov 3, 2011 19:40 |
|
shodanjr_gr posted:That's what I ended up doing. I create context on application launch and then any other contexts that are initialized share resources with that one context. This is way complicated. Have you tried a single OpenGL context that does all your GL rendering and passes the result back to your widgets? The widgets can update themselves as the rendering comes back. Remember: there's only one GPU so multiple threads will not help with the actual rendering. Also GPU and CPU resources are separate from each other unless you are using CLIENT_STORAGE or just mapping the buffers and using that CPU side. You can track what needs to be uploaded to the GPU by just making dirty bits and setting them. Multiple threads should not be trying to update the same GPU object at once in general - that gets nasty very fast.
|
# ? Nov 6, 2011 00:43 |
|
Spite posted:This is way complicated. Have you tried a single OpenGL context that does all your GL rendering and passes the result back to your widgets? The widgets can update themselves as the rendering comes back. Remember: there's only one GPU so multiple threads will not help with the actual rendering. You mean as in having a single class that manages the context and rendering requests get posted to that class which does Render-To-Texture for each request then returns the texture to a basic widget for display? quote:Also GPU and CPU resources are separate from each other unless you are using CLIENT_STORAGE or just mapping the buffers and using that CPU side. You can track what needs to be uploaded to the GPU by just making dirty bits and setting them. Multiple threads should not be trying to update the same GPU object at once in general - that gets nasty very fast. That's what I plan on doing...basically have each wrapper for my resources carry a CPU-side version ID and a GPU-side version ID and then a function that ensures consistency between the two versions. I am also providing a per-resource lock so technically more than one thread should not be locking the same resource for writing at the same time (either on the CPU or the GPU side).
|
# ? Nov 6, 2011 02:16 |
|
shodanjr_gr posted:You mean as in having a single class that manages the context and rendering requests get posted to that class which does Render-To-Texture for each request then returns the texture to a basic widget for display? That's how I'd approach it myself. Just post requests to this thread/object and have it pass back whatever is requested or necessary for the UI to draw. I'm making quite a few assumptions because I don't know exactly what your architecture needs to be, but it will vastly simplify your locking and GPU handling to do it that way. As for the second part, do you think multiple threads will be accessing the same CPU object simultaneously often? You can always make your CPU stuff more volatile - if you don't mind taking copies of stuff and passing that around/modifying the copy instead of locking. Your program's needs will better determine which will be more efficient.
|
# ? Nov 7, 2011 08:34 |
|
Crosspost from the game development thread, perhaps the folks here might have some opinions... Has anyone had problems with graphics 'stuttering?' I have a very simple test application (C#, SlimDX) where a textured quad (doesn't matter if I use the built-in Sprite class or manually fill my own vertex buffer) moves from left to right over and over, and about once per second there is a visible 'jump' of a few frames. I feel like I've tried everything and cannot figure out what it is. Garbage collection every frame, vsync on and off, etc etc. Eventually I tried the SlimDX samples that come with the SDK and found they that had the same problem, so now I think it's something wrong with my computer. I tried it on my laptop and had a similiar--but not quite as extreme--problem. It jumps a little bit, but not quite as dramatic on my main machine. Updated my video card (9800 gtx+) drivers to no avail. Turned on/off debug runtime in the DirectX control panel. I'm totally at a loss! I know this isn't perfect information, I'm just hoping someone has seen these symptoms before and knows what it is.
|
# ? Nov 8, 2011 21:35 |
|
Yikes, that's hard. It could be one of approximately a million things. I'm not familiar with slimdx but it's quite possible it's something with that? Do other 3d apps and games run fine? Have you tried writing a simple c d3d or opengl app that does the same thing?
|
# ? Nov 9, 2011 04:43 |
|
Stupid question incoming: I'm learning GLSL using the orange book. I couldn't use glAttachShader beacuse it wouldn't find it and googling around I found out that to use GLSL with SDL (which I'm using in an application in which I wanna use shaders) you have to setup some extensions and stuff. I'm guessing the functions in this extension do more or less the same than the ones mentioned in the orange book. My question is what's the difference from using the ARB extension one (glAttachObjectARB for example) or the ones mentioned in the book, like glAttachShader (which I'm not sure how to use with SDL). I've googled but I haven't found any information on which is the "right" way to do it, or what's the difference between them (if there's any). edit: After reading this http://www.opengl.org/wiki/Getting_started#Getting_Functions I downloaded glew, which I'm now using to load all this functions. Gonna try to write a simple shader and see if it works. Why does it have to be so hard? HolaMundo fucked around with this message at 22:50 on Nov 13, 2011 |
# ? Nov 13, 2011 21:16 |
|
edit: Okay, originally I said there was no difference, which is true, but you should have access to glAttachShader as long as you're using OpenGL 2.0 drivers. Static linking to the opengl32.lib library will only give you access to the symbols exposed by that library, you probably need to use something like SDL_GL_GetProcAddress to get other functions. Linking against the library is flaky in general and it's not uncommon for implementations to get every single function call they plan on using through GetProcAddress.
OneEightHundred fucked around with this message at 07:40 on Nov 14, 2011 |
# ? Nov 14, 2011 01:55 |
|
After using glew (which does all the GetProcAddress fun stuff) I got it working. I'm wondering why all the hassle (ok, maybe it's no that bad, heh) of having to use GetProcAddress to get the functions? Not like it matters now that I've got it working, just being curious.
|
# ? Nov 14, 2011 13:57 |
|
Because linking the library assumes the functions are there. It has some dangerous implications in that it can cause your app to flat-out not start if it's looking for functions that don't exist even if you don't plan on using them. Also because I think the opengl32.lib that ships with VS only has the 1.1 API calls.
|
# ? Nov 14, 2011 15:29 |
|
OneEightHundred posted:Because linking the library assumes the functions are there. It has some dangerous implications in that it can cause your app to flat-out not start if it's looking for functions that don't exist even if you don't plan on using them. Also because I think the opengl32.lib that ships with VS only has the 1.1 API calls. Couldn't someone create a stub opengl3.lib file for use? (I assume not, but AFAIK stub .lib files only contain the function names right?)
|
# ? Nov 14, 2011 16:07 |
|
Yes, you could do that. You'd still want to use GetProcAddress for anything that you weren't sure would be available (i.e. calls exposed by extensions).
|
# ? Nov 14, 2011 16:22 |
|
Unless you're running into some GLEW-related problem I don't really see a reason to bother, though.
|
# ? Nov 14, 2011 16:33 |
|
OneEightHundred posted:Yes, you could do that. You'd still want to use GetProcAddress for anything that you weren't sure would be available (i.e. calls exposed by extensions). Not really. What's happening is that wglGetProcAddress asks the driver for its implementations of the functions. So you'd need a .lib for each driver and probably each build of each driver. Then you'd need a separate exe for each and it would be nasty. This is also why you have to create a dummy context, get the new context creation function and create a new context if you want to use GL3+. It sucks.
|
# ? Nov 15, 2011 01:16 |
|
Oh right I forgot that you have to use wglGetProcAddress and regular GetProcAddress on the DLL doesn't really work. Yeah basically just have a structure that contains all of the functions you want and use that. It doesn't take that long to add new PFN*PROC types and add API calls as you go since there are only like 100 functions in the API worth using any more. Function pointer types for all of the extensions are already in glext.h
|
# ? Nov 15, 2011 01:40 |
|
Or just use GLEW because that what it already does and it's a solved problem.
|
# ? Nov 15, 2011 02:40 |
|
Spite posted:Not really. What's happening is that wglGetProcAddress asks the driver for its implementations of the functions. So you'd need a .lib for each driver and probably each build of each driver. Then you'd need a separate exe for each and it would be nasty. OneEightHundred posted:Oh right I forgot that you have to use wglGetProcAddress and regular GetProcAddress on the DLL doesn't really work. I had a feeling this is what was being done. (especially since I did a dumpbin to a .def file of the ATI drivers, and only about 24 functions are actually present within the opengl driver dll. some of which are for egl ) Paniolo posted:Or just use GLEW because that what it already does and it's a solved problem. There's also the gl3w library which focuses on using and loading only opengl 3/4 functions. One question though, on a slightly related matter. Since OpenCL works well with OpenGL, and there are a variety of implementations out there, writing for each implementation and distributing multiple executables isn't a factor because they didn't go the route of clGetProcAddress style system right?
|
# ? Nov 15, 2011 02:53 |
|
SAHChandler posted:One question though, on a slightly related matter. Since OpenCL works well with OpenGL, and there are a variety of implementations out there, writing for each implementation and distributing multiple executables isn't a factor because they didn't go the route of clGetProcAddress style system right? It is a factor precisely because they didn't go that route. I could be wrong because my experience with OpenCL is fairly limited but I believe currently if you link with the nVidia libs your executable will only run on a machine with nVidia drivers, and the same goes for the Intel and ATI implementations.
|
# ? Nov 15, 2011 17:18 |
|
Orzo posted:Crosspost from the game development thread, perhaps the folks here might have some opinions... I forgot I had f.lux installed and running in the background. Disabling it does not fix the problem, but exiting out of the program does.
|
# ? Nov 15, 2011 18:34 |
|
SAHChandler posted:I had a feeling this is what was being done. (especially since I did a dumpbin to a .def file of the ATI drivers, and only about 24 functions are actually present within the opengl driver dll. some of which are for egl ) There's an extension for ES2 compatibility, which is probably why they are there. As for OpenCL: also keep in mind that OpenCL is driven by Apple, which controls its driver stack and can release headers that work with all its parts.
|
# ? Nov 16, 2011 02:47 |
|
Paniolo posted:It is a factor precisely because they didn't go that route. I could be wrong because my experience with OpenCL is fairly limited but I believe currently if you link with the nVidia libs your executable will only run on a machine with nVidia drivers, and the same goes for the Intel and ATI implementations. I've looked at the headers and such, and I think the only issue would be anything involving the linker, but I assume because it's dynamic linking, all the function calls can be resolved at runtime. This is something that no documentation out there seems to talk about, as everyone who is writing opencl apps seems to assume people will be able to download and compile the source (which solves the distribution issue)
|
# ? Nov 16, 2011 06:47 |
|
More newbie questions! I've been learning glsl for the past few days and it's been kinda confusing since sometimes you find stuff for different version of glsl and I can't keep track of what should or shouldn't work. I understand the new versions of glsl have signficant changes from the older ones on how they work so I'm just using version 110 to teach me the basic stuff. Started by writing a simple fragment shader which just draws the whole screen in one color, that was easy. Next I decided to implement texture mapping (so I can try doing bump mapping later) but I'm having a hard time figuring out why my code is working / why it wasn't working before. Fragment shader: code:
code:
code:
Is the fragment shader just setting the sampler2D variable to whatever texture opengl is currently using? I'm guessing this is the case, since I can change the name of the variable in the fragment shader and it still works but I don't understand why it wouldn't work with glUniform1i(loc1, texMadera). Gah, this ended being kinda long. tldr: how the hell does my vertex shader know which texture I'm using?
|
# ? Nov 20, 2011 15:42 |
|
You tell the shader what texture UNIT you're using and you still bind that texture in your C code. That's why passing 0 seemed to work for you. You don't give it the texture ID.
|
# ? Nov 20, 2011 16:26 |
|
Doh! Thanks But why does it work if I change the variable name (of the sampler2D) in the vertex shader? Does it defaults to whatever texure is binded in unit 0 or something like that? I'm guessing for bump mapping you could bind the normal map to a different unit than the actual texture and pass both to the shader.
|
# ? Nov 20, 2011 17:01 |
|
HolaMundo posted:Doh! It's probably defaulting the value of that variable to 0, which is the first texture unit. And yes, for bump mapping, you would have multiple texture units and thus multiple sampler2D variables.
|
# ? Nov 20, 2011 19:51 |
|
Sampler2D is essentially a number that corresponds to the texture unit. Most GPUs have 16 these days. ie: glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_2D, tex) Will bind the texture 'tex' to unit 0. Then you set the sampler to 0 and it will sample from that texture. As for defaults, it will depend on the implementation. It should default to 0, but I'd check the spec to be sure.
|
# ? Nov 22, 2011 00:56 |
|
Is there a site with a solid rundown of GPU feature support these days? Delphi3D is hosed and it's a pain in the rear end trying to figure out what old hardware supports what render formats, what is supported as an input but not as a render target, what supports depth read and what only supports compare, and all of these other goofy pre-DX10 inconsistencies.
|
# ? Nov 22, 2011 01:38 |
|
If you want to do some cross referencing between GL and DX, try: http://developer.apple.com/graphicsimaging/opengl/capabilities/ I'd hope everything relatively recent/worth developing for supports depth read
|
# ? Nov 22, 2011 22:36 |
|
Spite posted:I'd hope everything relatively recent/worth developing for supports depth read That looks good though, guess everything I care about supports FP16 color buffers.
|
# ? Nov 22, 2011 23:58 |
|
OneEightHundred posted:Yeah looks like I was confusing the X1000-series' lack of PCF with what looks like pre-PS2.0 inability to sample depth textures as floats. The ATI X1xxxx series doesn't let you filter float textures in hardware, from what I recall. There's always room for a dirty shader hack though!
|
# ? Nov 23, 2011 01:09 |
|
How should I handle having multiple shaders? For example, I now have a normal mapping shader (which also handles texture mapping), but let's say I want to render something else with a texture but no normal map, how would I do that? Having another shader just for texture mapping seems stupid. Also thought about having a bool to turn normal mapping on or off but it doesn't seem right either.
|
# ? Nov 23, 2011 18:03 |
|
HolaMundo posted:How should I handle having multiple shaders? Yeah I think you're supposed to avoid conditionals and branching so the bool thing is not the best solution. I do something similar to what you want by using different techniques to compile different combinations of vertex and pixel shaders. In your example maybe you'd have one technique with normal mapping and one technique without it. Maybe it would be better to do it with multiple passes instead of techniques, but I haven't really done stuff in multiple passes. Mata fucked around with this message at 18:57 on Nov 23, 2011 |
# ? Nov 23, 2011 18:53 |
|
It's almost always preferable to a true conditional to run the extra calculations in all cases and multiply the result by 0 if you don't want it to contribute to the fragment.
|
# ? Nov 23, 2011 19:26 |
|
I haven't touched GPU stuff in a while, but I was under the impression that static branches based on global uniform variables will be optimized away by all modern compilers/drivers and never get executed on the GPU, so it wouldn't make a significant difference either way...? Best way to find out is benchmark both, I guess
|
# ? Nov 24, 2011 00:00 |
|
|
# ? Jun 3, 2024 21:38 |
|
Thanks for the answers. What I'm doing now is have two separate shaders (one for texture mapping, the other for normal mapping) and switch between them depending on what I want to render.
|
# ? Nov 24, 2011 01:45 |