* Render passes and framebuffers can have as many attachments as desired, and
just use a small subset in each subpass. We shouldn't add an artificial limit
without good reason.
* When selecting a marker region, the more intuitive search is to find children
of the marker first before searching onwards, even if the 'current event' is
at the end of the marker region.
* Sometimes a GLES implementation can refuse to copy back the 'native'
format/type, most commonly if you want to read back from a GL_RGB texture it
might require you to readback GL_RGBA.
* We handle this by just reading back the requested format in this case, and
then copying only RGB tightly into the output buffer.
* Unfortunately it seems like sometimes in GL when creating an GL_RGB
internalformat texture you can copy from another GL_RGB internalformat
texture. Other times you can't.
* In particular the difference can just be the 'type' parameter passed when
passing initial data, GL_UNSIGNED_BYTE vs eGL_UNSIGNED_SHORT_5_6_5
* We treat this as a 'soft' hint, so if it's not present we fall back to the old
path.
* In particular it wasn't added until GLES 3.1, and we need it during capture to
determine the uniforms and other things, so we emulate the subset of queries
that we need ourselves.
* This is only to be used to make a temporary context to share with. We make
sure to use the same visual/config as the parent context to ensure it will
successfully share.
* We need to hack around GLES, as it somehow added only part of the original
extension - non-arrayed textures. So we conceptually split up the extension
into two, and treat the real extension as a superset.
* This function is not available until 3.1 so we can't rely on being able to use
it - even if we get a valid function pointer for it.
* We emulate it by storing the data up front and allowing the emulation layer
access to our texture info to look it up. It's a bit roundabout but it works.
* We need to be sure the context pair has been updated before serialising the
state, otherwise any resources we query out will be associated with
potentially the wrong context.
* This code was significantly different from the old code, enough that it made
more sense to re-implement from scratch than modify the old code.
* Note it doesn't compile yet and is not included in any projects.
* We have a hookset per GL interface - WGL, GLX, and stubbed out CGL for mac. In
addition we have EGL which can be compiled in at the same time as the others.
Each interface has a dispatch table similar to GL for handling its hooks all
together.
* The platform hooksets hook their platform-specific functions like
createcontext, swapbuffers, and makecurrent. For getprocaddress they can call
into a common function that looks up general GL hooks.
* EGL and GLX can populate the GL hooks using eglGetProcAddress /
glXGetProcAddress as soon as the library is loaded, but for WGL we must wait
until the first time a context becomes current.
* We also have an implementation of GLPlatform per type. This takes care of work
that is platform specific - mostly during replay but also somewhat during
capture. This is kept separate from the actual hooks.
* On replay we have a platform-specific replay create entry point which
populuates the relevant dispatch table and calls into a general replay create.
This will do most common work together but calls out to the GLPlatform
implementation to do actual initialisation of the API.
* In particular, populating hooks can't fail because we're just fetching as many
function pointers as we can. Any missing functions have to be handled
elsewhere.
* This simplifies codepaths and makes it easier to track what's going on without
needing to thinkg about failure conditions that can never happen.
* Hooking is now done the same way across platform, with different OS
implementations.
* Regardless of how exactly hooks are implemented, we register libraries to hook
and functions to hook within those libraries, and provide a location to store
the original/onwards function pointer. This allows hooking to work whether
it's done using import hooking that doesn't modify target libraries (so using
dlsym or GetProcAddress will return the same value for the onwards function
pointer) or whether it's implemented with prologue patching and trampolines,
where we'd create an infinite loop if we did that.
* We also provide stronger guarantees - the original function pointers will
_always_ be made available as soon as the library is loaded, whether hooked or
not, no exceptions. This means less uncertainty in hooking code about when or
how onward functions will be available.
* OS-specific hook functions are changed to just be implementations of
LibraryHooks functions rather than indirected through macros and pre-processor
definitions.
* In this commit we provide some temporary functions providing the old interface
to reduce churn - the library-specific hook code will be updated shortly after
* Hooking no longer does anything active immediately when initialised, it just
registers a function to be hooked, which is then deferred and/or continually
re-hooked depending on platform-specific functionality.