This is used to declare that a `VkDeviceMemory` object is for the sole
use of a particular buffer or image.
In fact, until Metal 1.2 on iOS (2.0 on Mac), Metal didn't really
support anything *but* dedicated allocations. MoltenVK hacks around this
limitation by manually syncing memory between buffers and images that
used the `VkDeviceMemory` object.
Maybe someday we can use the new `MTLHeap` object to support some sort
of sub-allocation scheme. But at this moment, it won't let you specify
the exact offset within the heap, nor can it be used for managed or (on
macOS) shared memory, nor will it let you directly map the heap memory
(something that could be worked around with an aliasable `MTLBuffer`
taking up the entire heap space), all of which makes it unsuitable for
implementing `VkDeviceMemory`. So, for now, we always prefer dedicated
allocation.
This means that arrays in the `Uniform` storage class decorated with
`Block` or `BufferBlock` (or in the `StorageBuffer` class with `Block`)
can be indexed with dynamically uniform constants. I see nothing in the
MSL spec which forbids this.
We really don't care about the `Format` specified on an `Image` type in
SPIR-V modules. MSL doesn't even have a place to specify it. (This is of
course referring to the pixel format, as opposed to the data type, which
we *do* care about.)
Metal supports read-only access from shaders to multisampled
textures--in fact, it's the only way they're supported. (Aside from as a
render target, of course.)
`#include` this file to define the various bits and pieces needed to
support an extension. Now instead of having to change three places, we
now only need change one.
Also, sort the list of extensions. This list is starting to get a little
long and unruly, so before it gets completely out of hand, let's apply a
little semblance of order to it. The extensions are now arranged in the
following order: first, the Khronos-blessed extensions; then multivendor
extensions; then our (`MVK`) extensions; and finally other vendors'
extensions. These subgroups are sorted alphabetically, as Khronos'
master list is.
I'm not happy about the `MVK_EXTENSION_LAST` kluge. But, C++ apparently
doesn't let you stick a dangling comma on a constructor's initializer
list.
Clients can now set multiple viewports and scissor rects, but without a
geometry shader, it won't be much use. For now, however, we can support
`VK_EXT_shader_viewport_index_layer`, which will make this feature more
useful despite us not having geometry shaders.
Add MVKConfiguration member prefillMetalCommandBuffers and build setting
MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS.
Rename MVKConfiguration member maxActiveMetalCommandBuffersPerPool
to maxActiveMetalCommandBuffersPerQueue.
Support Xcode 10 build settings.
This is for fragment shaders that run per-sample instead of
per-fragment. It implies that the `SampleId`, `SampleMask`, and
`SamplePosition` builtins, as well as per-sample interpolation, are all
available--using any of these causes the frag shader to run once per
sample. (In Metal, reading the color buffers may also cause a frag
shader to run per-sample.)
Update SPIRV-Cross to pull in a change that properly translates the
`SamplePosition` builtin to a form that Metal can understand.
The spec requires all implementations of Vulkan to support this, so we
may as well turn it on. I haven't seen any ill effects from
out-of-bounds accesses, so I think we'll be OK.
This requires Metal 1.2 (for the `MTLPixelFormatX24_Stencil8` and
`MTLPixelFormatX32_Stencil8` formats). Since Vulkan doesn't actually
have a corresponding format for that, add a new Metal feature for this.
Bump extension spec version.
Just add it to the buffer offset when encoding the command. The reason
for this is that we were using it to index the buffer--which, according
to the C++ spec (on which MSL is based), causes it to be offset by that
many 32-bit words instead of bytes. This caused the buffer to be filled
incorrectly. While Metal does require the offset to be aligned to the
type size (in this case, 4 bytes), Vulkan also requires the offset to
`vkCmdFillBuffer()` to be 4-byte aligned, so this shouldn't run into the
same problem as `vkCmdCopyBuffer()`.
For a copy, the spec requires only that the source and destination
bindings are valid, not that the source has been initialized. If the
source binding hasn't been initialized, then we crash attempting to get
the Metal resources corresponding to the uninitialized descriptors. So,
if the descriptor binding hasn't been initialized, don't try to fetch
Metal resources for it.
Yes, this causes us to accept writes of NULL descriptors (from
templates or otherwise), even though the spec forbids this. I don't know
how to solve this without specializing `writeDescriptorSets()`
specifically for the `VkCopyDescriptorSet` case (thereby duplicating
quite a bit of code). Given the general nature of Vulkan as a framework
that does little to no state validation, I wonder if it's even worth it.
Also, warn only when the texture may be used for a purpose other than as
a color attachment. Fail outright if it won't ever be used for that
purpose, or if the view doesn't cover the entirety of the volume.
The problem is that on 64-bit platforms (i.e. every platform we support)
there will be padding between the `sType` and `pNext` members of any
extensible Vulkan structure, because `sType` is only 4 bytes while
`pNext` is 8 (and needs 8-byte alignment).
Should fix a segfault running `vulkaninfo`.
This won't help using these image views from shaders, but it will help
attaching them to framebuffers.
I've left the warning in `validateImageViewConfig()` in place.