* This lets us detect if the FBO/VAO behaviour is different from the main
spec, and so we won't miss deletes or other events if the context is
different since we'll treat them as shared like any other object.
* This means you don't hit a debugbreak and fire an exception in profile if
you load an image file (which tries to load as a logfile first, and
fails).
* Important buffer chunks like the first glBindBuffer and glBufferStorage
could happen in the frame, so need to preserve order between those and
glTexBuffer.
* It is only replayed in READING, so once at startup - not once per frame
replay.
* None of these require extra serialisation functions, but some upgraded
to DSA style serialise instead of selector serialise functions.
* There's a lot of duplication here now (expecially for MultiTex calls).
This could really do with cleanup soon.
* In OpenGL and D3D11, resource handles (pointers or namespace/uint pairs
respectively) could be reused, so we can't use these to denote resources
that are getting updated regularly and should have updates ignored.
* I don't know how I got away with this for so long, or why I used pointers
in the first place. It could have predated resource IDs maybe.
* Until I have a proper UI this is convenient when capturing, especially if
you point the folder at a samba share on windows so you can load the
capture up directly.
* This avoids spamming of glReadBuffer/glDrawBuffer calls pointlessly into
the pre-frame chunk stream.
* The default FBO stores its ReadBuffer and DrawBuffers in the initial
frame state vector.
* When an unpack buffer is bound, don't serialise out any data for any
function. For glTexImage* style creation functions we still need the
create to be serialised, but we can immediately mark it dirty and fetch
the real data later. We just pass NULL for the data pointer.
* For glCompresssedTexImage*, we can't pass a NULL data pointer, so we
create a scratch buffer that's big enough to create the image of the
correct size, and allow the initial data from it being marked as dirty
to then overwrite it later.
* glTexSubImage style functions should be replayed even when executing, in
case new data is uploaded mid-frame.
* If GL_NEAREST is specified it means the whole mip chain is locked off,
even if we do textureLod in the shader.
* Instead, go back to using GL_NEAREST_MIPMAP_NEAREST and clamp the
MAX_LEVEL to make the texture mipmap complete when necessary.
* We need to serialise out the new state vector that's applied when we
change context.
* Note we still have very hacky incomplete support of contexts, and no
support of true threading. We currently assume all contexts share with
all others, and if any actual parallel rendering happened it would break.
* It's handled already on the C++ side by binding a point or linear sampler
to that slot, but also it seems that it's not well defined (that I can
see) if texelFetch should sRGB decode or not. On nvidia it seems to, but
on AMD it seems like it doesn't do the decode.
* On nvidia it seems that doing glCopyImageSubData() on a D32F_S8 texture
can cause serious problems, so ignore it for now. We can generally get
away with it, as usually the only depth buffer in this format is the
'main' depth buffer, which isn't used frame-to-frame.
* If a buffer gets marked as dirty before being mapped as persistent (e.g.
mapped for write & not invalidate), we won't hit this warning and then if
the buffer map is truly persistent forever, we'll never see the map again
to warn during frame capture!
* If we're ignoring a map it's marked correctly as dirty, but otherwise a
buffer could be mapped once then not touched, not become dirty, and so
we need the unmap chunk in its record.
* We track as little state as possible - basically only objects bound to
binding points that we need to identify for old-style non-DSA functions.
This is mostly for convenience - the best balance between tracking GL's
_insane_ state vector and having to query everything we want every time.
* Although we don't properly handle multiple contexts, we need to make sure
this state is tracked per context otherwise we can get weird mismatches
and get crashes with e.g. invalid VAOs.