-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redundant glXGetProcAddressARB-calls severely reducing performance #171
Comments
Epoxy needs to test the version and supported extensions before dispatching a function, as it takes care of handling the different API:
We cannot really cache the version and extension checks once performed, because you could call the same function using difference contexts; we could find a way to cache things a bit better, though. On the other hand, querying the version and extensions should return static data and it's typically not a synchronization point: it should not affect performance in a drastic way. Are you enabling some debugging state? |
I do wonder, though, if you're using OpenGL < 3.2 and the old fixed function pipeline — and you're calling Can you create a small, self-contained example? |
This looks more like the resolver is being called every time. As if the variable holding the function pointer wasn't being updated. |
Our caller may load (eg) epoxy_glAlphaFunc, which is a function pointer, and then call through that value multiple times. Until the caller re-examines the value of that function pointer, which is a copy relocation in the executable, repeated calls mean repeated work resolving the GL function. We can't make the caller reinspect the variable, but the resolver function can avoid doing redundant work. Fixes: anholt#171 Signed-off-by: Adam Jackson <ajax@redhat.com>
Sorry for not replying earlier, didn't have much time to spend on this in the last few days. @nwnk That patch works very well, performance is now almost identical to not using libepoxy! @ebassi The code can be configured to use OpenGL 1.1 or 2.1, but it uses glVertexPointer and friends instead of glBegin/glEnd. My reason for using libepoxy was to get rid of the manual function pointer handling for shaders and compressed textures. Afaik the code doesn't use any special debugging stuff. |
@thrimbor well I'm glad it helps, but I'm concerned that it'd be needed. Your code doesn't look like it's trying to save function addresses, so I would naively think that calling I wonder if this is a funny interaction with linking with |
@nwnk Changing that has the same positive effect on performance. |
Epoxy updates the function pointers in order to avoid calling the resolver multiple times, but with -Bsymbolic we're going to update the copy inside libepoxy, instead of the relocated copy in the code using libepoxy. This leads to libepoxy constantly querying the function resolver code instead of just once. We still want to avoid intra-library relocations for our functions, but we need to live with them for our global function pointers. See issue #171
Opened #174 with the linker flag change only, but given the testing, we should likely merge both. |
Epoxy updates the function pointers in order to avoid calling the resolver multiple times, but with -Bsymbolic we're going to update the copy inside libepoxy, instead of the relocated copy in the code using libepoxy. This leads to libepoxy constantly querying the function resolver code instead of just once. We still want to avoid intra-library relocations for our functions, but we need to live with them for our global function pointers. See issue #171
Our caller may load (eg) epoxy_glAlphaFunc, which is a function pointer, and then call through that value multiple times. Until the caller re-examines the value of that function pointer, which is a copy relocation in the executable, repeated calls mean repeated work resolving the GL function. We can't make the caller reinspect the variable, but the resolver function can avoid doing redundant work. Fixes: #171 Signed-off-by: Adam Jackson <ajax@redhat.com>
This may be something stupid on my side, but maybe someone can shed some light on this.
I recently tried to use libepoxy in an attempt to port an SDL+OpenGL based game to Windows (the relevant commit is this one).
However, using libepoxy on Linux resulted in a drastic performance loss: The fps dropped from over 3000 to ~500, even dropping below 30 in some areas - which is extremely strange for such a simple renderer.
Further analysis showed that libepoxy does a significant amount of redundant GL-calls (glXGetCurrentContext, glGetString and glXGetProcAddressARB) before every call to an OpenGL function (here is an analysis of a single frame).
I ran it on Arch Linux with a GTX 970 (390.48 driver), and I tried libepoxy 1.5.0 and 1.5.1 (and 1.4.0 a while back, I think). Arch Linux doesn't seem to do anything special when building the package.
I'm not sure what the problem is here, I expected libepoxy to only query the addresses once. Are there known problems combining libepoxy with SDL (version 1), or am I hitting a bug here?
The text was updated successfully, but these errors were encountered: