It doesn't allow anything except full RGBA and 32-bit types to be read
from the framebuffer. Chromium browsers weren't complaining but Firefox
did. I remember a similar restriction from GLES2 but all implementations
I tested with including ANGLE and SwiftShader allow that already, so
it's practically just a WebGL limitation.
This doesn't actually fix the WebGL-specific error (there it
additionally disallows mismatched signedness in a vertex attribute) but
is nevertheless good to have correct.
Unlike most other extensions, this one has to be explicitly enabled in
Emscripten in order to be used. Which thus done as part of other "driver
workarounds" done on startup. To avoid that, the extension can be
explicitly disabled, and thanks to the previous commit the disabling
will be performed before the extension is attempted to be enabled.
Because a MeshView might not be the best thing to have when you are
submitting a batch of thousand draws. It takes a strided array views to
allow for more flexibility, but can also detect if the input is already
contiguous and use it as-is.
UNFORTUNATELY the GL 1.0 legacy still continues to stink and so there
has to be a 64-bit-specific overload which is the *actual* variant that
doesn't allocate because glMultiDrawElements takes a `void**` for INDEX
OFFSETS and it's IN BYTES! Which foolish soul designed such a thing back
in the 1860s, I wonder. There's no reason to not have an index offset
in elements because all indices have to have the same type ANYWAY. And
yes, I wasted about three hours debugging driver crashes because I
THOUGHT this parameter takes offset in elements, not bytes.
Also note: on 32-bit platforms this depends on latest Corrade with the
CORRADE_TARGET_32BIT definition. Spent an embarrassing amount of time
wondering why all local builds but Emscripten work.
Or, the horror when I comment-out half of it and it still kinda passes.
The new code tests it more thoroughly, with actually checking that
different draw produce different results instead of one draw overwriting
the other.
Plus also verifying interaction with gl_VertexID and gl_DrawID to ensure
it really behaves correctly:
- gl_VertexID should get the same value regardless of whether we
perform a multi-draw or a one-by-one fallback, so this catches issues
where the mesh would get reconfigured in some nasty way, losing this
information
- gl_DrawID should get properly populated if and only if we use the
multi-draw code path, so this catches issues where the fallback would
get used instead of the actual multi-draw code path
Also test it properly and add a check for extension availability. Sigh,
seems like nobody ran this test on an Apple device since this thing got
added in 75d238f50b ...
The 32-bit float depth be needed for the upcoming OpenEXR plugin, added
also the remaining ones that will be eventually supported by KTX and DDS
plugins.
Its only use was for specifying N-dimensional SamplerWrapping because,
compared to a Math::Vector, it had an implicit constructor from a single
value (whereas the Vector has it explicit). I solved that by simply
adding a few single-value overloads where it mattered. There, done. No
need for this weird thing and confusion with Containers::Array anymore.
All places that used it now use Math::VectorN<SamplerWrapping>, but the
class is still included for backwards compatibility purposes, together
with providing implicit conversion from and to a Vector.
Ah the good old times where my brain was not overflowing with
unnecessarily deep knowledge about how GPUs (and OpenGL drivers in
particular) work. Nope, switching a blend state and calling glFinish()
won't generate any GPU work, that will be all deferred until there's
something to be actually drawn, cleared or copied.
'cuz I was writing some raw GL for Emscripten tests and arrived at
glClear(GL_COLOR);
without having any suspicion that this is just TOTALLY WRONG. Same
would go for Vulkan few years ahead when I'm so used to the Magnum
wrappers that I forget what the common pitfalls are.
There are no SSO / DSA extensions on that platform, so it doesn't make
sense to do this extra indirection. Saves another kilobyte (237 -> 236
kB) in WebGL 2 magnum-gl-info.wasm.
Instead of wrapping glProgramUniform*() inside a member function, we now
call that function directly, which allows us to remove 2/3rds of
AbstractShaderProgram members. The non-DSA code path is still
implemented though member functions, though they are now static,
mimic the signature of the DSA APIs and do a use() + glUniform*()
internally.
With this flag set (which is done implicitly for all windowless apps
and, conversely, not done for all windowed apps), the default
framebuffer state isn't touched in any way, which should avoid potential
race conditions with default framebuffer on another thread.
This means that instead of 12 separate allocations we have just one,
allocating everything together in a contiguous piece of memory. That
should be also a bit more cache friendly when accessing the state as
it's not scattered around the memory like crazy.
Because there are no Pointer indirections needed anymore, the State
members are just references now. That resulted in a lot of sweeping
changes around the whole GL library, but they're all trivial, changing
`->` to `.`, mostly.
There's two more nested allocations in the TextureState struct, will
take care of them in a separate commit.