Using openMemory() instead of openData() allows the implementation to
assume the data will stay in scope for as long as needed, which can
prevent unnecessary copies in some plugin implementations.
It warranted a new flag, DataFlag::ExternallyOwned, to describe this
kind of memory. I couldn't reuse Owned as that's used for allocations
owned by the instance, which is too little for certain future use cases.
For example returning *Data instances referencing an Owned memory would
mean the user has to assume the memory is gone when the importer
instance is gone, and that's generally not true for memory passed to
openMemory().
Originally I thought I would do this later, but then realized the
existing plugin implementations would need to get all updated again to
be aware of the new flag, with some being forgotten, and it's just
easier to do the whole thing in a single step.
This allows to better describe memory ownership and transfer it instead
of forcing the plugins to allocate their own local copy if the import
happens in-place on the imported data. Right now that's mainly for the
openFile() use case, which implicitly allocated an Array with file
contents only to pass it to openData() which then made a copy because it
could not make any assumption about data scope.
In other words, certain plugins (TgaImporter, KtxImporter, DdsImporter,
CgltfImporter and possibly others) will now have their peak memory usage
*halved*.
Hah, so many overloads. Not providing mutable access to keys or layer
offsets as that would break the invariant of the internal array always
being sorted.
And update docs in Matrix[34]::rotation() and related functions to note
this. This is a breaking change that may cause existing code to start
asserting.
Interestingly enough, there were no docs whatsoever for image and scene
conversion, and neither it was mentioned what all scene data can be
imported. Sigh.
Breaking this macro yet again, sorry -- now the result values are
specified last and there can be any number of them, however they need to
be all prefixed, as adding the prefix implicitly with the macro would be
too much of a pain to implement, especially given the poor preprocessor
capabilities of MSVC.
Together with DescriptorBindingFlags, because it affects the design in a
rather specific way and it wouldn't make sense to postpone this and
forget all again until it becomes needed.
Together with SamplerFilter, SamplerMipmap and SamplerWrapping enums
convertible from the generic versions, which finally deprecate the
last remaining vk*() conversion functions in Enums.h and thus the whole
header as well. The EnumsTest executable is also no more, as the rest of
it now resides inside SamplerTest.
We're going to eventually include this class in all Application classes
(need that in order to inherit a to-be-created Configuration class) and
the <string> and <vector> would be just too much. This change caused
magnum-gl-info.wasm (WebGL 2 build) to go down from 247 to 245 kB. Not
much, but that's I guess because there's still a lot other vectors of
strings elsewhere.
There's a lot more places to clean up, will do those in separate
commits. This change is the most atomic I could do, and it introduces a
breaking change to all APIs that returned a std::vector or a
std::string. Fortunately (or as I hope) those weren't used that much, so
it shouldn't cause build breakages for that many people.
Quite a lot of the optimization ideas is borrowed from the new Vk
library -- such as "interning" the driver workaround strings to avoid
allocating their copies.
Together with:
* CommandBuffer::draw()
* Support for indexed and non-indexed meshes
* Support for setting primitive and stride dynamically
I took one shortcut and vkCmdBindVertexBuffers() is currently called
once for each binding. The interface is ready for this, but I'm not yet
100% sure how to test that it actually does batch the buffers, so it's
left at the lazy implementation for now.
I named it RasterizationPipelineCreateInfo and not
GraphicsPipelineCreateInfo because there's now a
RayTracingPipelineCreateInfo as well, which is *also* graphics, and it
would be confusing for everyone except people already drowned in Vulkan
naming quirks.
Next up is *the unthinkable*, a Vk::Mesh. After that I'll finally have
enough APIs exposed to document everything including command buffer
recording and submission.
These were implemented long before ArrayTuple was a thing and while the
allocation saving optimization makes sense, the implementation is way
too error prone.
This also means Array (and thus <new> and other heavy shit) isn't
included in the headers, which leads to further slimming of compile
times across the library.
Since depth/stencil images can't be linear, I needed buffer/image copies
to test those, and conversely to test buffer/image copies I needed image
clears.
A pretty big chunk of work, and it led to a discovery of a SwiftShader
bug, which I will work around next. First Vulkan driver workaround, so
the whole scaffolding needs to get added as well.
Because (after I read a bunch of articles on this) it can actually be
understood easier that way -- the now-documented snippet shows that in
practice. Also expanded the constructor and usage docs a bit.
Originally I wanted to save people typing and provide "reasonable
defaults" for the image layout, however shortly after I realized I can't
express even the simplest case in the Vulkan Triangle example with
those.
Furthermore the case of having default load/store operations are so
rare that it isn't worth an extra API which tricks the user into
thinking the clear/discard operations are meant to be done somewhere
else. I realized this because it was actually harder to explain these in
a second step than introducing them right from the beginning.
Finally, because there's so many different structures to fill, the
implicit constructors weren't a good idea either, as it again tricked
users to think just PixelFormat or just an index is the parameter, with
nothing else, and then left them wondering where all the other important
params go. Same with {} used instead AttachmentLoadOperation::Load /
AttachmentStoreOperation::Store, unnecessary confusion there so don't
even suggest that.
I was slowly getting cancer from having to write the unreadably awful
VK_FORMAT_R666G666B666A666_SRGB all the time. Besides that:
- All pixel formats are documented to show what's guaranteed for them
by the spec. Pretty useful I'd say.
- The old hasVkFormat() and vkFormat() converters operating on a
VkFormat are deprecated in favor of new hasPixelFormat() and
pixelFormat() that use the PixelFormat enum. Similarly as done in the
GL wrapper.
- All APIs that took a VkFormat before take a PixelFormat now, together
with having conveinience overloads for Magnum::PixelFormat and
Magnum::CompressedPixelFormat. Again similarly as done in the GL
wrapper, also the first step on being able to *directly* use data
imported with the Trade library with Vulkan.