Among other things this makes it possible to use Utility::copy() instead
of a manual loop and grow arrays with std::realloc() instead of always
new'ing-copy-deleting because Containers::Pair is trivially copyable.
This significantly simplifies everything -- because a single type can
now handle both StringView lists and char* lists, we no longer need a
templated private helper to avoid allocating a temporary array of
unified type. Instead, the whole extension initialization can be done
directly in the initialize() helper, by simply iterating over the
argument.
Yay, this is probably the nicest improvement caused by StringIterable so
far.
Because it somewhat confusingly may have implied that it's really
composed of 8-bit bools, and not bits. The same reasoning was used to
pick the name for Corrade's Containers::BitArray.
Backwards compatibility aliases are in place as usual, however the
internal BoolVectorConverter is now BitVectorConverter and there
unfortunately cannot be any backwards compatibility. This breaks only
GLM and Eigen integration in the magnum-integration repo, which I'm
fixing immediately. I don't expect any user code to use this internal
helper. For regular vectors maybe, for this one definitely not.
There was a nasty issue when moving the Device -- because the Queue
instances are populated with the Device pointer in the constructor,
moving the Device makes the Queue device pointer invalid and those
instances are useless. Discovered this when using VulkanTester to test
an upcoming Queue::submit() -- until then, the Device pointer in the
Queue wasn't really used for anything and so this wasn't known.
Making the Device immovable is thus the only sane way to keep the
current Queue retrieval workflow, which I'd say is much cleaner than
having to manually query the device for queues later using some
error-prone indices and whatnot. On the other hand, this finally makes
it possible to have a failable device creation, instead of the device
creation failing on an assert (or failing silently when
CORRADE_NO_ASSERT is defined). This is consistent with how the GL
wrapper works.
Also, because all device-dependent objects need to keep a pointer to the
originating Device in order to access Vulkan function pointers, having
it immovable makes it considerably faster. I'll make Instance immovable
with tryCreate() next because it seems like a good thing to do there as
well.
This was way more pain that initially expected, especially in regards to
preserving externally-specified pNext chains without writing to them in
any way.
After I implemented the render pass wrapper, seeing how the
RenderPassCreateInfo structure and its dependencies were HUGE compared
to the actual tiny and lean RenderPass, I felt uneasy dragging their
definition along to every place where a RenderPass gets used. It's not
as bad with the others, but as new extensions are implemented I expect
that to get the same.
This change makes it easier for me to accept that Image.h / Buffer.h
depends on Memory.h. There isn't a real measurable difference when
building Magnum itself (50 ms out of 7 seconds for the Vk library
alone), but that's because most of the code (and tests) needs the
CreateInfo structures anyway.
Although the APIs don't look like that right now, in many cases creation
of a particular Vulkan object isn't all that's there for it. So change
the section names from a generic "Usage" to "Creation".
Thus it has no place in the general overview docs of Vk::Instance and
Vk::Device. Better to put it into the VUlkan wrapping docs, where it
also makes sense to have both the device and instance side together.
More convenient to use since one doesn't have to explicitly store a
DeviceProperties instance to call pickQueueFamily() on it and then move
it to DeviceCreateInfo to keep it efficient.
This required a slight redesign of how DeviceProperties are stored in
DeviceCreateInfo, now we need the instance to be always valid (but it
can get never used). The wrap() API isn't doing any extra work so this
won't add any inefficiency.
Today I spent six hours wrongly convincing myself that it's a driver bug
when vkGetPhysicalDeviceProperties2() is null on a 1.1 instance for a
1.0 physical device. It's not a bug, it's me not reading specs
carefully.
This commit thus basically moves all Instance-level extension-dependent
state to DeviceProperties, because it's actually device-dependent. Which
makes the DeviceProperties class quite heavy and thus it's good it was
readied to be transferred all the way to a Device instance a few commits
back -- I don't really want to do all the dispatch, string processing,
sorting and other mess more times than strictly necessary.
In addition, DeviceProperties::apiVersion() got renamed to version() and
a new isVersionSupported() API got added, mirroring what's on Device
itself; plus thanks to the chicken-and-egg problem of having to call
vkGetPhysicalDeviceProperties() twice, the device version and other
things can now be retrieved in a slightly more efficient way.
I have more and more cases where I need to query device properties later
down the road (memory capabilities, device name, ...) and leaving all
this up to the user / making this impossible to do in the library
internals is complicating everything too much.
Since there's a shitton of device properties with a new bag of props
coming with every other new extension, I expect the queries to get quite
involved / complicated over time (chaining 100s structs and such), so
let's design this upfront in a way that can avoid reqpeatedly querying
the same thing just because we needlessly discarded a fully populated
instance before.
It also means the users don't need to drag their own DeviceProperties
instance along anymore and can just let the Device take care of that.
Unfortunately the only nice way to make this work with DeviceCreateInfo
method chaining is to add & and && overloads for each. But it's quite
easy to test that all of them work and properly return a r-value
reference so it shouldn't be too much of a maintenance nightmare.
Everything what was in src/ is now in src/Corrade, everything from
src/Plugins is now in src/MagnumPlugins, everything from external/ is in
src/MagnumExternal. Added new CMakeLists.txt file and updated the other
ones for the moves, no other change was made. If MAGNUM_BUILD_DEPRECATED
is set, everything compiles and installs like previously except for the
plugins, which are now in MagnumPlugins and not in Magnum/Plugins.
* Older GLSL doesn't have texelFetch() and related things, working
around it by using classical texture() and normalized floating-point
coordinates. But that needs to have Texture::imageSize() passed,
which is not available in OpenGL ES, thus the user must specify it
explicitly there. On desktop OpenGL that parameter is ignored.
* Older GLSL doesn't have gl_VertexID, thus vertex buffer must be
created and vertex data passed expliticly.
* GLSL ES 2.0 doesn't have one-component texture format and
TextureFormat::Luminance probably isn't renderable anywhere, thus
TextureFormat::RGB should be used, although it is inefficient.
* Checking for framebuffer completeness, if not complete, nothing is
done.
* Re-eabled building of TextureTools library in all ES PKGBUILDs.