While this function is already marked `unsafe` to represent cases where
an invalid pointer might be dereferenced, it should at least be obvious
to the caller that there is a real chance for `NULL` pointers in these
`CStr` getters, which will now be returned as `None`. This function
won't be used in `Debug` now as the dereference operation is still
`unsafe`.
The `_as_c_str()` getters for static arrays is left untouched, as the
data is read directly from the known-valid struct here.
Upstream Vulkan is okay with the request to annotate static arrays with
a `len="structField"` annotation when the size of the static arrary
is bounded by a value at runtime. This allows us to generate more
convenient builder functions that copy slices into the target "builder"
struct while _also_ updating the length, rather than forcing the caller
to move an array of the desired length with zeroed elements and setting
the length field separately.
In addition provide a safe getter (and use it in the `Debug`
implementation) to return a slice view containing only valid items
per the length field. As with strings this is only possible for
static-sized arrays as we can never safely dereference a random pointer.
Rust 1.75 has once again gotten a bit more complete/strict when
linting code. `.get(0)` is now recommended to be replaced with
`.first()`, and needless glob reexports are equally denied (the modules
in question either contain macros which are already reexported via
`#[macro_export]`, or contain `impl` blocks exclusively which cannot be
referred to as item paths either).
All structs are marked as `Copy`, and builders move `self` for a
convenient builder pattern directly on `default()` (using `&mut`
requires requires first keeping the instance alive in a `let` binding).
This however leads to builder functions accidentally moving a copy of
`self`, mutating it, and dropping the result directly when the caller
did not consume the returned value in ad-hoc field updates, in turn
leaving the author confused why their code compiles without warnings
while the struct was not updated.
Annotating all Vulkan structs with `#[must_use]` should at least give
them an idea why.
Certain structs contain sized character arrays that are converted to
`CStr` for convenient accss to the user and our `Debug` implementation
using unsafe `CStr::from_ptr(...as_ptr())`. There is no need to
round-trip to a pointer and possibly read out of bounds if the
NUL-terminator index (string length) is instead searched for by the
newly stabilized `CStr::from_bytes_until_nul()` fn since Rust 1.69
(which panics if no NUL-terminator is found before the end of the
slice).
Unfortunately `unsafe` is still needed to cast the array from a `c_char`
(`i8` on most platforms) to `u8`, which is what `from_bytes_until_nul()`
accepts.
In essence this builder function needs to adhere to two rules:
1. No ref-after-free: the slice must outlive (uses of) the builder
object;
2. No aliasing: the slice cannot be (im)mutably used while it is mutably
borrowed within a live builder object.
These two rules have been tested and are satisfied by the given builder
implementation. Without this change `timings` seems to be borrowing
itself, hence is not allowed to be used after it has been temporarily
mutably borrowed inside the builder, even after that builder was
dropped. Thus defeating the purpose of this "getter" API via a struct.
Without the `.cast()`, because mutable raw pointers are invariant
(i.e. there is no subtyping relationship) the compiler complains about
requiring `self` to outlive `timings` instead, which does not satisfy
the two rules above.
* Convert `mem::zeroed()` / `0` to `MaybeUninit::uninit()`
As noted in #792 changes like this might help us more strictly identify
and validate that the argument in question is only relevant as an output
argument (i.e. structs with `sType` are read by the function call, even
if the caller strictly expects return values there, so that it can fill
in multiple structures in a `pNext` chain, and must hence be `Default`-
initialized).
* Use uninit `Vec`s with late `set_len()` call instead of zero-initialization
* Use `uninit()` instead of `-1` for file descriptors
* Introduce `set_vec_len_on_success()` helper for `Vec::with_capacity()`
It is a common operation to read and write NUL-terminated C string in
the Vulkan API, yet the only helpers for that were thus far open-coded
in the `Debug` printing implementations.
Move them to separate functions that are exposed to the user, in hopes
of helping them no longer misunderstand NUL-terminated strings (see
e.g. #830).
Important to note is that the array-copy for a static-sized `c_char`
array has also been replaced with a `CStr` wrapper: this forces the user
and our implementation to have a NUL-terminator at the end of the string,
and the setter returns `Err()` when the given `CStr (with NUL-terminator)
is too large for the static-sized array it has to be written to.
* Update Vulkan-Headers to 1.3.270
* Update Vulkan-Headers to 1.3.271
* extensions/nv/low_latency2: Support extension revision 2
Upon request the VK_NV_low_latency2 spec and API has been updated to move
the count pointer from the `vkGetLatencyTimingsNV()` function to
the `vkGetLatencyMarkerInfoNV` struct where the array pointer already
resided.
This got uncovered when it was realized that the `latency_marker_info`
argument isn't an array at all (which the original design of this
extension suggested), but a pointer to a single struct that _contains_
a pointer to an array, with the length passed as a separate argument to
the function instead.
The move of this count argument to a struct field - together with proper
array length annotations - gets our generator to automatically emit a
setter based on a slice argument.
In an identical fashion to commit 84624fd ("ray_tracing_pipeline:
Pass SBT regions as reference instead of slice (#350)")
`cmd_trace_rays_indirect()` also only needs a pointer to a single
`StridedDeviceAddressRegionKHR` structure. After all no length is ever
passed to the API anywhere, and this could also lead to users passing
empty slices, or passing too many elements that are never used.
Clear up the confusion by replacing the slice argument with a direct
borrow of the struct.
Since a few Rust versions `cargo` complains:
warning: virtual workspace defaulting to `resolver = "1"` despite one or more workspace members being on edition 2021 which implies `resolver = "2"`
Avoid that by setting the resolver for the virtual manifest to `"2"`
explicitly.
[Dependabot complains] that:
the binary target name `examples` is forbidden, it conflicts with with cargo's build directory names
And fails to provide dependency upgrades for Rust code. Fix that by
renaming the folder and crate to `ash-examples`.
[Dependabot complains]: https://github.com/ash-rs/ash/network/updates/748770724
Some links were still pointing to the (moved) `MaikKlein/ash` repo,
instead of the new shared `ash-rs/ash` repository under this
organisation, GitHub still provides a redirect, but we should aim to
provide the correct link from the get-go. Only the gitter channel
remains as it was impossible to get the room to be renamed. The
`ash-rs/ash` channel exists but there is currently no activity.
Even though we don't have many dependencies, our GitHub Actions are
getting severely out of date and are best updated to the latest version.
Let dependabot help us with this, together with the few `cargo` crate
dependencies that we have (mainly in examples).
This parameter is not only used for the length of `pImageInfo`,
`pBufferInfo` or `pTexelBufferView`, but also matching the value
of `dataSize` when `VkWriteDescriptorSetInlineUniformBlock` is
appended in `pNext`, or the value of `accelerationStructureCount`
when `VkWriteDescriptorSetAccelerationStructureKHR` is in `pNext`.
Having the count setter directly avaialble makes builder code more
natural, instead of having to use a `mut` variable and manually assign
`.descriptor_count = xx.len();` afterwards.
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkWriteDescriptorSet.html
* generator: Add many missing lifetime parameters
* Globally find-replace common patterns that need a `<'_>` lifetime annotation
perl -pi -E "s/(&(mut )?\[?vk::(?\!\w+(V1_\d|Fn|<))\w+)/\$1<'_>/" **/*.{rs,md}
* generator: Include aliased types in `has_lifetime` lookup table
* Manually revert wrong find-replace lifetimes
* Resolve lint warnings for `deprecated_in_future`, `rust_2018_idioms` and `unused_qualifications`
These are 3 non-default lints that cause a lot of violations in this
project that are sensible to resolve, and reduce noise when
test-including a local `ash` checkout in other projects that have
stricter lint setups.
* CI: Cross-lint for Mac, iOS and Windows
We have some conditional code specific to Mac and iOS which is currently
untested in the CI, allowing non-compiling code in PRs like #795 to go
unnoticed.
* Fix new clippy lints
* Update Vulkan-Headers to 1.3.255
* Update Vulkan-Headers to 1.3.257
* Update Vulkan-Headers to 1.3.258
* Update Vulkan-Headers to 1.3.259
* Update Vulkan-Headers to 1.3.260
* Update Vulkan-Headers to 1.3.252
* Update Vulkan-Headers to 1.3.253
* Update Vulkan-Headers to 1.3.254
* vk/platform_types: Add `_screen_buffer` type for QNX
Ash doesn't implement `Drop` intentionally, to not be too opinionated
about holding (heap) references to their parent objects
(`Device`->`Instance`->`Entry`) and ensuring they are destroyed in the
right order. As such, reword the `create` documentation for `Instance`
and `Device` to mention their respective `destroy_*` function instead of
referring to them as being "droppable".
Note that `Entry` is droppable as it does not have a Vulkan `destroy`
function _and_ the dynamically loaded library (behind the "loaded"
feature) is kept alive only for the lifetime of `Entry`.