The "end of pipeline" referred to by this command is the internal
hardware pipeline, not the entire command stream. The current
OpenGL driver has no pipeline, so the command should be executed
immediately.
True coreinit.rpl behaviour is that interrupt are disabled whenever
there is a scheduler lock active. We have elided this due to our
C++ code being uninteruptible, but this causes issues when games
already have interrupts disabled and then do a rescheduling
operation. We have to force-enable them for the switch instead.
This caused allocations that fit exactly to fail to be
allocated due to adjSize being increased to allow alignment
as a pre-step. This modifies it to check for the ability
to do alignment on a per-block basis instead.
This is a re-reverse of the above mentioned structures based
on all knowledge gained since their first pass. This fixes
some minor differences which were not caught before.
The meaning of the OpenGL query TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
is not well-defined by the specification, and the API reference
documentation claims that it returns a vertex count, but in fact it
returns a primitive count as the name suggests, so we need to
calculate the vertex count ourselves when updating buffer offsets.
Since safely reading from a persistently mapped buffer requires a
glFinish() call, we instead avoid maps entirely for output buffers
and call glGetNamedBufferSubData() to let the driver sync for us
(with potentially finer granularity).
If the program performs several draw operations in a row before calling
GX2SaveStreamOutContext(), we don't need to update our copy of the
current offset on every draw.
Also move transform-feedback code to its own source file to make it
easier to locate.
We could potentially see a query started without the previous query
having ended, if the program decides to reset the GPU (on a timeout,
for example) in the middle of the previous query.
This also removes an unneccessary reschedule. Since if the
thread still owns the mutex and only decremented its recursive
count, then no other thread can take it yet anyways.
"Recently" is defined by an update generation counter; the counter is
stored with each uniform(*) when one of its component registers is
written, and is incremented and saved with a shader after uploading
changed uniforms, where "changed" is detected as a uniform whose last
write generation is not less than the shader's last upload generation.
(*) To be precise, uniform change state is tracked in groups of 16
uniform vectors (64 registers), as a balance between the cost of
uploading too much unchanged data to the host GPU and the cost of
checking the changed status of each uniform individually.
In addition to reducing the amount of data uploaded to the host GPU,
this typically reduces the number of GL calls per frame by 5-10% (due
to cases where no uniforms have changed at all), and as a bonus it
significantly improves the replay speed of GL trace files.