* By the logic that means we need to iterate into the VAO/FBO bound
objects on frame start, we also need to do for bound VAOs and FBOs
later in the frame.
* Also FBO state needs to include the actual attached objects and their
attachment parameters, since this information is lost when we stop
tracking FBOs.
* To simplify things we assume there won't be any user swizzling on
luminance or alpha textures, and just apply our own to emulate rather
than attempting to store & stack them.
* We used to switch to the context that the object was created on and
fetch initial state there, but this isn't safe e.g. the switch
operation could fail if the context was active on another thread.
Instead we queue up such objects to have their data fetched the next
time we see the context made current.
* If we never get the initial state for that object we assume that
context is never used, so it's OK to just not have initial states -
it's marked as invalid so we don't try to restore those states on
replay.
* Note: this obviously falls down in the even that the context is
already current on another thread and we just get commands from there
without an explicit 'MakeCurrent' call. But we already don't handle
that as we don't detect that and log the state change (or properly
handle multithreaded commands), so it's not any worse support.
* We can't just link ALL programs as separable to be safe, since this
hits the same problem of some shaders not being valid as separable :(.
* This should fix the case where a separable program with initial state
was failing to link before, without breaking non-separable programs.
* This is invalid since we are talking about real FBOs, not the default
FBO, but it might come up in compatibility context programs and it's
harmless to correct to try and replay correctly.
* Technically we need to try and restore the VAOs even if disabled to the
correct setup, so that if they're just enabled they are in the expected
state. However if the attribs are in an invalid state it's not legal to
just enable them again, so they need to be respecified anyway.
* This might have something to do with compatibility profiles - it was
seen capturing Wolfenstein: The New Order, which runs 3.2 compatibility.
* If the pixel store parameters are relatively simple we go through a
fast path that's about the same as it was before, otherwise we manually
unpack to a tightly packed buffer for serialising. Hopefully this should
rarely happen.
* glPixelStore parameters are only serialised when capturing a frame, and
the pixel store parameters at frame start form part of the initial state
vector.
* Also added handling for dirty buffer textures - there are no contents to
copy, those are handled with the buffer, so instead we just grab the few
parameters that are valid to re-specify the buffer texture.
* We pick up the properties of VAO 0 on frame capture as dirty state, and
then replay it into the fake VAO we were already creating for VAO 0.
* Eventually this record will be entirely trimmed/ignored for programs that
don't use VAO 0 by frame references, but for now we fetch it needlessly.
It doesn't seem to fire any errors.
* If the 'context shared' VAOs/FBOs hack is on, their context is set to
NULL (so any context will match the resource), but this also means we
shouldn't try and bind that context to fetch data.
* 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 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.
* 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.
* When we do glCopyImageSubData, this seems to require a complete texture
across all mips - ie. the full mip chain (up to MAX_LEVEL) must be set.
This requirement holds even if we only copy the mips that are present.
* However, for example attaching an image to a framebuffer, it doesn't
have to be mipmap complete even if the min/mag filters want mipmaps.
So in this case we have to force the texture to be complete enough for
our purposes, and we do this just by setting MAX_LEVEL to clamp the mips
* If you're capturing and replaying on the same driver it's insanely
unlikely that this translation will be anything other than the identity
map, although it wouldn't be illegal to renumber locations. However this
should allow moving captures between vendors/driver versions/platforms,
which in the past wasn't possible because locations would change (quite
validly) when the programs were recompiled. There might be other issues,
but at least this one is fixed.