* The unpack parameters are ignored for compressed images unless the
compressed width, height, depth and size parameters are set (whichever
are required for the given unpack param). So we roll this into our
calculation of the fast path, which means that we only use them in
UnpackCompressed if they are valid.
* This can happen when we're copying from a source program to a dest
program where the source is non-separable and had an attribute
optimised out entirely, but the destination is separable and so still
wants that attribute. In this case it'll come out in the wash and
we can just skip it.
* 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.
* Apparently although there are no errors thrown if you pass
GL_ALL_BARRIER_BITS (0xffffffff), if you remove a bit then an error
will be thrown for unrecognised bits :(.
* Since it's not harmful to leave in the mapped buffer bit we just let
it remain.
* We need a context to be current when the frame capture happens so that
we can fetch initial contents and such. This is a hack as there's no
guarantee it's correct or will work, but we temporarily make the last
context that was active on this thread active again, to fetch our
data.
* This could break if that context is active elsewhere, or isn't a valid
context (ie. maybe it was a temporary context used to fetch func
pointers).
* A better fix would be to delay any GL work we need to do until the
next time a good context becomes current, but that becomes dicey in
itself.
* Note that we serialise out the new render state any time we reach a
MakeCurrent call, so we can safely 'skip' the initial render state
at the start of a frame.
* 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.
* These are placed a little conservatively to be sure we pick up changes
* They're placed on any drawcall, any buffer copy operation, any texture
data operation that can source from a buffer via pixel unpack buffers,
any texture copy or read (like framebuffer blits) since the buffer
could be a texture buffer. Also on any function that returns the
contents of a texture or buffer.
* Should support coherent & non-coherent persistent maps (coherent
coming with a fair performance hit).
* Slightly changed the method from the one planned - coherent maps don't
need to actually be mapped coherently. Since we're inserting a manual
sync & copy point all over the place, we can map the underlying GL
buffer as non-coherent and flush explicit, then just do the flushes
when we do the copies.
* Still need to add all those implicit sync point calls, and I'm sure
there are plenty of bugs in this implementation.
* The documentation also describes how persistent maps will be handled
in the code to follow.
* There are a couple of edge-case bugfixes here that turned up as I was
writing up how everything should work:
- a high traffic resource wasn't being marked as dirty, which probably
wouldn't ever break as if we ever acted on it being high traffic, we
would mark it dirty, but better to be explicit.
- fetching initial shadow storage contents in capframe, we need to
fill the whole buffer, not just the mapped region.
- if a flush explicit map were non-invalidating, it could be
intercepted even while idle, but then the flush calls would have
been discarded and never gone anywhere while idle. Instead we just
explicitly don't intercept flush explicit maps except while
capturing
* glMapBuffer can just be expressed in terms of glMapBufferRange, this
simplifies the flow a bit.
* We can also romeve a couple of map statuses, as they're no longer
used.
* Also, buffer creation chunks must go into the resource record, not the
context record, in case a buffer is created in the frame that's
captured.
* This should be impossible, as Map() is only valid after glBufferData
or glBufferStorage, and both of those will unconditionally set a data
pointer to backing store.
* This was always a problem, but may have been hidden in some cases by
lack of DSA type use causing a late bind-to-create. e.g. in a VAO we
might have been binding an element array buffer that caused a bind-to-
create on the VAO. Now we do it in the glGen functions to ensure the
objects are fully initialised.
* For the most part these are identical to the equivalent glGen*.
* For textures, we bake in the current type immediately, for buffers we
would ideally want a type but the glCreateBuffers doesn't take one (it
then gets renamed/retyped).
* Since this would be another duplicated set of code, move the variants
into common functions - each of the variants (ARB_dsa, EXT_dsa,
non-DSA and possibly MultiTex) calls into a common function just with
a different resource record.
* Handling the ARB/EXT dsa differences on the texture calls, the target
parameter is set to GL_NONE for the ARB dsa calls (which lack a target
parameter). Then in the serialise replay part, if the target is
GL_NONE we use the ARB variant and otherwise use the EXT variant.
See the comments at the top of gl_texture_funcs.cpp
* For functions with common code that needs to happen on replay, we pass
the resource's ID instead of its record, to be compatible with replay
where there are no records. To save time & unnecessary queries, also
force all internal texture creates on replay to happen through the
DSA interfaces so we don't have to go looking up the texture via
selectors.
* Doesn't compile yet! Just splitting this up logically so the change is
a bit easier to digest.
* I've commented and organised a bit better the gl_hookset.h hook list.
* The function hooks are set up for all of the ARB_dsa entry points.
Those that are semnatically identical to EXT_dsa are set up as aliases
(with EXT_ being canonical, so we can fall back if ARB_dsa isn't
supported - see comments in gl_hookset.h).
* Implemented the new functions except for the glTexture* family and the
glCreate* family. No deduplication of code yet.
* As with EXT_dsa we "promote" to the DSA function for serialisation,
but since unlike EXT_dsa we can't assume ARB_dsa is present, instead
we emulate those functions that we might use unconditionally but may
not be present.
* We make the ReplaceResource call recursive - so if we replace a shader
it will replace any programs that use that shader recursively and next
iteration if we are replacing a program, we replace any pipelines that
use it.
* In D3D11 the RTs and UAVs have the same namespace, but GL has separate
framebuffer attachments and images. This change splits up the concepts
so the D3D11 case is a special case, in a way, and that we can handle
any generic mix of the two nicely.
* We have a separable program for each shader that we can use to mess
about with and relink for doing overlay/analysis type stuff. We need
to make sure we create it properly and don't use re-use the separable
program that is the 'real' version.
* For each texture you view, it will reset back to mip 0 and slice 0
as it previously did, and it will also reset the channels back to
RGB only, which is new behaviour.
* Then each texture remembers those settings, so if you choose to view
slice 6 & alpha only of a texture any time you switch back to it
you'll see slice 6 & alpha only.
* It can be disabled in the options, but this is the new default
behaviour. Possibly in future the zoom level and visible range might
be rolled into this, but for now I think they might work better as
global state.
* This means these will spam errors if anyone is using a feature level
10.x or below device without ps_5_0 support, but that's unavoidable
and not too important (in release it'll just be some log spam).
* The implementation needs the fine dFdx/dFdy variants, which are only
available in GLSL 4.50 and above. Without that support we fall back
to the normal dFdx/dFdy which are implementation dependent. In my
quick test on nvidia it so happened that it was still fine, but that's
not guaranteed.
* Since we decode the visual colours into an integer by looking them up
in the overdraw ramp rather than re-running to get an integer return,
we make some invisibly subtly different colours above the highest
overdraw colour, and use these to tell overdraw levels above 20.
* Since the addition of the normalised UV co-ords the status bar will
flicker in width horrendously when scanning over a texture and it's
impossible to track where you are. Even worse, if the text is wide
enough (or the window narrow enough) you'll end up with the status
bar flickering between one and two lines - which is awful.
* For now I've added some padding for numbers and set a fixed width font
so the only varying element is the actual texel value, which is
unavoidable in the general case. The text is probably wider overall
so I'll need to see what feedback I get.
* glsl and hlsl custom display shaders are kept separate, and only shown
for the appropriate log type.
* The little snippets added in the shader editor aren't updated yet, and
none of the pre-defined shader constants are filled out.