Skip to content
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

WIP Trace and replay ANGLE (EGL & GLES) on Windows #764

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

chrisdjali-wrld3d
Copy link

Hopefully this doesn't break anything else that already worked. It's also got a few other unrelated fixes for things that were causing problems during testing.

Although this doesn't work with the application I'd intended to use it with yet (due to a threading regression in ANGLE tracked as https://bugs.chromium.org/p/angleproject/issues/detail?id=6427), it should work with other applications compatible with vaguely up-to-date ANGLE versions. Hopefully that means it's useful to people and also reviewable. However, I'm seeing a problem with some other applications where the tracing functions are calling themselves instead of the originals which I've not go to the bottom of yet.

It uses the vcpkg port of ANGLE instead of the official Google version as Google offer no binaries and require DepotTools to build it, and then there's no FindANGLE.cmake or anything like that, so it would have been a hassle to do it any other way.

jrfonseca and others added 18 commits May 26, 2021 16:01
Untested but a starting point to trace Angle on Windows.

apitrace#522
Roughly matching ANGLE's exports.
Now Surfaces tab will be disabled when it's meant to be.
There's no supported way to stop ANGLE logging to stdout, but we need to
dump things via stdout. As it uses stdout directly and we use std::cout,
it's possible to change the file descriptor to go nowhere and keep
std::cout intact.

Swapping out stdout for something else is relatively simple, but doing
so while keeping std::cout going to the original location requires
duplicating the original file descriptor and replacing the internal
buffer. That requires OS-specific calls and vendor-specific STL
extensions, so I've only implemented it for Windows so far. Other parts
of this branch are already potentially Windows-specific anyway.
@chrisdjali-wrld3d chrisdjali-wrld3d marked this pull request as draft October 6, 2021 18:06
@chrisdjali-wrld3d
Copy link
Author

The recursion issue looks to be because of this feature of LoadLibraryA:

If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first.

The application I was originally working with loads ANGLE immediately as it's got the DLLs in its import table, whereas the others I tried load it manually later on. The injector injects the tracing DLL in between those events, so depending on the application, one or the other can be loaded first, and therefore returned by LoadLibraryA.

@chrisdjali-wrld3d
Copy link
Author

That last commit fixes the case where our DLL is loaded before the real one, but not the other failing case where it's loaded instead of the real one.

@chrisdjali-wrld3d
Copy link
Author

@jrfonseca I've got a trace that won't load in the GUI properly (no calls are displayed) and apitrace dump is missing 121 eglGetConfigAttrib calls. It just covers an application picking a GLES config, creating the context, and dying, so I could understand the GUI not displaying anything as no actual GLES calls happened, and eglGetConfigAttrib might be something that would be hidden given that they wouldn't replay. Are these bugs in my branch, or expected behaviour?

It outputs

0 eglGetDisplay(display_id = NULL) = 0x1a89e8623d0
1 eglInitialize(dpy = 0x1a89e8623d0, major = NULL, minor = NULL) = EGL_TRUE
2 eglGetConfigs(dpy = 0x1a89e8623d0, configs = NULL, config_size = 0, num_config = &15) = EGL_TRUE
3 eglGetConfigs(dpy = 0x1a89e8623d0, configs = {0x1a8a55c3a90, 0x1a8a55c4120, 0x1a8a55c27d0, 0x1a8a55c3b80, 0x1a8a55c2d70, 0x1a8a55c4300, 0x1a8a55c3e50, 0x1a8a55c3c70, 0x1a8a55c3220, 0x1a8a55c2b90, 0x1a8a55c38b0, 0x1a8a55c29b0, 0x1a8a55c4210, 0x1a8a55c2c80, 0x1a8a55c39a0}, config_size = 15, num_config = &15) = EGL_TRUE
125 eglCreateWindowSurface(dpy = 0x1a89e8623d0, config = 0x1a8a55c3220, win = 0x4b1c00, attrib_list = {}) = 0x1a8a0130ec0
126 eglCreateContext(dpy = 0x1a89e8623d0, config = 0x1a8a55c3220, share_context = NULL, attrib_list = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_NONE}) = 0x1a8a1488450
127 eglQuerySurface(dpy = 0x1a89e8623d0, surface = 0x1a8a0130ec0, attribute = EGL_WIDTH, value = &1350) = EGL_TRUE

trace.zip

Zero-length reads return -1, which decreased the size, making it negative.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants