Skip to content

Commit

Permalink
[wgpu-hal] Upgrade to ash 0.38
Browse files Browse the repository at this point in the history
https://github.com/ash-rs/ash/releases/tag/0.38.0

In this release a lot of breaking changes have been made: builder
structs are dropped in favour of always having a lifetime parameter
available on every raw Vulkan structure (when they contain one or
more pointers).  This massively contributes to lifetime (and mutable
aliasing) safety, but requires significant changes to some uses in
`wgpu-hal`.

All function pointer loaders for both Vulkan core and extensions
have moved into the root of `ash::`, making `ash::vk::` a more pure
`sys`-like module.  Extensions have their own `ash::<prefix>::<ext>`
module to clearly separate and group their items from the core.  Besides
`NAME` and the usual `*Fn` wrappers, the handwritten `extensions` module
is now only available via this path.  This to combat the
previous inconsistency between `ash::KhrSomeExtFn::name()` vs
`ash::extensions::khr::SomeExt::name()`.

The Vulkan core clearly splits functions across `device` and `instance`
functions, to keep functions that can be loaded without a dispatch-table
for a device via `get_device_proc_addr()` apart from instance functions.
This concept has now been applied to extension functions, making it
possible to load them optimized for a device too (when the shared
table would previously include instance functions and require the whole
thing to be loaded via `get_instance_proc_addr()`), and in the rare
case of 3 hand-written extension wrappers: load instance functions via
`get_device_proc_addr()` resulting in `NULL` pointers.

Finally, a few new helpers like `_as_slice()` and `_as_c_str()` are
available (the former only for statically-sized struct-owned arrays with
a length delimiter field) to simplify commonly written patterns.
  • Loading branch information
MarijnS95 committed Apr 8, 2024
1 parent 17ef6ca commit 09d3daf
Show file tree
Hide file tree
Showing 10 changed files with 562 additions and 676 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ Bottom level categories:
#### Vulkan

- Set object labels when the DEBUG flag is set, even if the VALIDATION flag is disabled. By @DJMcNab in [#5345](https://github.com/gfx-rs/wgpu/pull/5345).
- Upgrade `ash` to `0.38`. By @MarijnS95 in [#5504](https://github.com/gfx-rs/wgpu/pull/5504).

#### Metal

Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ objc = "0.2.5"

# Vulkan dependencies
android_system_properties = "0.1.1"
ash = "0.37.3"
ash = "0.38.0"
gpu-alloc = "0.6"
gpu-descriptor = "0.2"

Expand Down
4 changes: 2 additions & 2 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ gles = [
"khronos-egl",
"libloading",
"ndk-sys",
"winapi/libloaderapi",
]
dx12 = [
"naga/hlsl-out",
Expand Down Expand Up @@ -114,7 +115,7 @@ version = "0.19.0"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# backend: Vulkan
ash = { version = "0.37.3", optional = true }
ash = { version = "0.38.0", optional = true }
gpu-alloc = { version = "0.6", optional = true }
gpu-descriptor = { version = "0.2", optional = true }
smallvec = { version = "1", optional = true, features = ["union"] }
Expand Down Expand Up @@ -142,7 +143,6 @@ glutin_wgl_sys = { version = "0.5", optional = true }

winapi = { version = "0.3", features = [
"profileapi",
"libloaderapi",
"windef",
"winuser",
"dcomp",
Expand Down
21 changes: 0 additions & 21 deletions wgpu-hal/src/auxil/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,3 @@ impl crate::TextureCopy {
self.size = self.size.min(&max_src_size).min(&max_dst_size);
}
}

/// Construct a `CStr` from a byte slice, up to the first zero byte.
///
/// Return a `CStr` extending from the start of `bytes` up to and
/// including the first zero byte. If there is no zero byte in
/// `bytes`, return `None`.
///
/// This can be removed when `CStr::from_bytes_until_nul` is stabilized.
/// ([#95027](https://github.com/rust-lang/rust/issues/95027))
#[allow(dead_code)]
pub(crate) fn cstr_from_bytes_until_nul(bytes: &[std::os::raw::c_char]) -> Option<&std::ffi::CStr> {
if bytes.contains(&0) {
// Safety for `CStr::from_ptr`:
// - We've ensured that the slice does contain a null terminator.
// - The range is valid to read, because the slice covers it.
// - The memory won't be changed, because the slice borrows it.
unsafe { Some(std::ffi::CStr::from_ptr(bytes.as_ptr())) }
} else {
None
}
}
379 changes: 177 additions & 202 deletions wgpu-hal/src/vulkan/adapter.rs

Large diffs are not rendered by default.

104 changes: 42 additions & 62 deletions wgpu-hal/src/vulkan/command.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::conv;

use arrayvec::ArrayVec;
use ash::{extensions::ext, vk};
use ash::{ext, vk};

use std::{mem, ops::Range, slice};

Expand Down Expand Up @@ -39,12 +39,6 @@ impl super::Texture {
}
}

impl super::DeviceShared {
fn debug_messenger(&self) -> Option<&ext::DebugUtils> {
Some(&self.instance.debug_utils.as_ref()?.extension)
}
}

impl super::CommandEncoder {
fn write_pass_end_timestamp_if_requested(&mut self) {
if let Some((query_set, index)) = self.end_of_pass_timer_query.take() {
Expand All @@ -65,31 +59,23 @@ impl crate::CommandEncoder for super::CommandEncoder {

unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> {
if self.free.is_empty() {
let vk_info = vk::CommandBufferAllocateInfo::builder()
let vk_info = vk::CommandBufferAllocateInfo::default()
.command_pool(self.raw)
.command_buffer_count(ALLOCATION_GRANULARITY)
.build();
.command_buffer_count(ALLOCATION_GRANULARITY);
let cmd_buf_vec = unsafe { self.device.raw.allocate_command_buffers(&vk_info)? };
self.free.extend(cmd_buf_vec);
}
let raw = self.free.pop().unwrap();

// Set the name unconditionally, since there might be a
// previous name assigned to this.
unsafe {
self.device.set_object_name(
vk::ObjectType::COMMAND_BUFFER,
raw,
label.unwrap_or_default(),
)
};
unsafe { self.device.set_object_name(raw, label.unwrap_or_default()) };

// Reset this in case the last renderpass was never ended.
self.rpass_debug_marker_active = false;

let vk_info = vk::CommandBufferBeginInfo::builder()
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT)
.build();
let vk_info = vk::CommandBufferBeginInfo::default()
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT);
unsafe { self.device.raw.begin_command_buffer(raw, &vk_info) }?;
self.active = raw;

Expand Down Expand Up @@ -140,12 +126,11 @@ impl crate::CommandEncoder for super::CommandEncoder {
dst_stages |= dst_stage;

vk_barriers.push(
vk::BufferMemoryBarrier::builder()
vk::BufferMemoryBarrier::default()
.buffer(bar.buffer.raw)
.size(vk::WHOLE_SIZE)
.src_access_mask(src_access)
.dst_access_mask(dst_access)
.build(),
.dst_access_mask(dst_access),
)
}

Expand Down Expand Up @@ -187,14 +172,13 @@ impl crate::CommandEncoder for super::CommandEncoder {
dst_stages |= dst_stage;

vk_barriers.push(
vk::ImageMemoryBarrier::builder()
vk::ImageMemoryBarrier::default()
.image(bar.texture.raw)
.subresource_range(range)
.src_access_mask(src_access)
.dst_access_mask(dst_access)
.old_layout(src_layout)
.new_layout(dst_layout)
.build(),
.new_layout(dst_layout),
);
}

Expand Down Expand Up @@ -437,7 +421,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
Some(buffer) => ray_tracing_functions
.buffer_device_address
.get_buffer_device_address(
&vk::BufferDeviceAddressInfo::builder().buffer(buffer.raw),
&vk::BufferDeviceAddressInfo::default().buffer(buffer.raw),
),
None => panic!("Buffers are required to build acceleration structures"),
}
Expand All @@ -464,23 +448,24 @@ impl crate::CommandEncoder for super::CommandEncoder {
for desc in descriptors {
let (geometries, ranges) = match *desc.entries {
crate::AccelerationStructureEntries::Instances(ref instances) => {
let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::builder(
let instance_data = vk::AccelerationStructureGeometryInstancesDataKHR::default(
// TODO: Code is so large that rustfmt refuses to treat this... :(
)
.data(vk::DeviceOrHostAddressConstKHR {
device_address: get_device_address(instances.buffer),
});

let geometry = vk::AccelerationStructureGeometryKHR::builder()
let geometry = vk::AccelerationStructureGeometryKHR::default()
.geometry_type(vk::GeometryTypeKHR::INSTANCES)
.geometry(vk::AccelerationStructureGeometryDataKHR {
instances: *instance_data,
instances: instance_data,
});

let range = vk::AccelerationStructureBuildRangeInfoKHR::builder()
let range = vk::AccelerationStructureBuildRangeInfoKHR::default()
.primitive_count(instances.count)
.primitive_offset(instances.offset);

(smallvec::smallvec![*geometry], smallvec::smallvec![*range])
(smallvec::smallvec![geometry], smallvec::smallvec![range])
}
crate::AccelerationStructureEntries::Triangles(ref in_geometries) => {
let mut ranges = smallvec::SmallVec::<
Expand All @@ -491,15 +476,15 @@ impl crate::CommandEncoder for super::CommandEncoder {
>::with_capacity(in_geometries.len());
for triangles in in_geometries {
let mut triangle_data =
vk::AccelerationStructureGeometryTrianglesDataKHR::builder()
vk::AccelerationStructureGeometryTrianglesDataKHR::default()
.vertex_data(vk::DeviceOrHostAddressConstKHR {
device_address: get_device_address(triangles.vertex_buffer),
})
.vertex_format(conv::map_vertex_format(triangles.vertex_format))
.max_vertex(triangles.vertex_count)
.vertex_stride(triangles.vertex_stride);

let mut range = vk::AccelerationStructureBuildRangeInfoKHR::builder();
let mut range = vk::AccelerationStructureBuildRangeInfoKHR::default();

if let Some(ref indices) = triangles.indices {
triangle_data = triangle_data
Expand All @@ -523,7 +508,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
ray_tracing_functions
.buffer_device_address
.get_buffer_device_address(
&vk::BufferDeviceAddressInfo::builder()
&vk::BufferDeviceAddressInfo::default()
.buffer(transform.buffer.raw),
)
};
Expand All @@ -535,17 +520,17 @@ impl crate::CommandEncoder for super::CommandEncoder {
range = range.transform_offset(transform.offset);
}

let geometry = vk::AccelerationStructureGeometryKHR::builder()
let geometry = vk::AccelerationStructureGeometryKHR::default()
.geometry_type(vk::GeometryTypeKHR::TRIANGLES)
.geometry(vk::AccelerationStructureGeometryDataKHR {
triangles: *triangle_data,
triangles: triangle_data,
})
.flags(conv::map_acceleration_structure_geometry_flags(
triangles.flags,
));

geometries.push(*geometry);
ranges.push(*range);
geometries.push(geometry);
ranges.push(range);
}
(geometries, ranges)
}
Expand All @@ -557,25 +542,25 @@ impl crate::CommandEncoder for super::CommandEncoder {
[vk::AccelerationStructureGeometryKHR; CAPACITY_INNER],
>::with_capacity(in_geometries.len());
for aabb in in_geometries {
let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::builder()
let aabbs_data = vk::AccelerationStructureGeometryAabbsDataKHR::default()
.data(vk::DeviceOrHostAddressConstKHR {
device_address: get_device_address(aabb.buffer),
})
.stride(aabb.stride);

let range = vk::AccelerationStructureBuildRangeInfoKHR::builder()
let range = vk::AccelerationStructureBuildRangeInfoKHR::default()
.primitive_count(aabb.count)
.primitive_offset(aabb.offset);

let geometry = vk::AccelerationStructureGeometryKHR::builder()
let geometry = vk::AccelerationStructureGeometryKHR::default()
.geometry_type(vk::GeometryTypeKHR::AABBS)
.geometry(vk::AccelerationStructureGeometryDataKHR {
aabbs: *aabbs_data,
aabbs: aabbs_data,
})
.flags(conv::map_acceleration_structure_geometry_flags(aabb.flags));

geometries.push(*geometry);
ranges.push(*range);
geometries.push(geometry);
ranges.push(range);
}
(geometries, ranges)
}
Expand All @@ -588,7 +573,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
ray_tracing_functions
.buffer_device_address
.get_buffer_device_address(
&vk::BufferDeviceAddressInfo::builder().buffer(desc.scratch_buffer.raw),
&vk::BufferDeviceAddressInfo::default().buffer(desc.scratch_buffer.raw),
)
};
let ty = match *desc.entries {
Expand All @@ -597,7 +582,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
}
_ => vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL,
};
let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::builder()
let mut geometry_info = vk::AccelerationStructureBuildGeometryInfoKHR::default()
.ty(ty)
.mode(conv::map_acceleration_structure_build_mode(desc.mode))
.flags(conv::map_acceleration_structure_flags(desc.flags))
Expand All @@ -613,7 +598,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
.raw;
}

geometry_infos.push(*geometry_info);
geometry_infos.push(geometry_info);
}

for (i, geometry_info) in geometry_infos.iter_mut().enumerate() {
Expand Down Expand Up @@ -644,10 +629,9 @@ impl crate::CommandEncoder for super::CommandEncoder {
src_stage | vk::PipelineStageFlags::TOP_OF_PIPE,
dst_stage | vk::PipelineStageFlags::BOTTOM_OF_PIPE,
vk::DependencyFlags::empty(),
&[vk::MemoryBarrier::builder()
&[vk::MemoryBarrier::default()
.src_access_mask(src_access)
.dst_access_mask(dst_access)
.build()],
.dst_access_mask(dst_access)],
&[],
&[],
)
Expand Down Expand Up @@ -749,17 +733,13 @@ impl crate::CommandEncoder for super::CommandEncoder {
.make_framebuffer(fb_key, raw_pass, desc.label)
.unwrap();

let mut vk_info = vk::RenderPassBeginInfo::builder()
let mut vk_info = vk::RenderPassBeginInfo::default()
.render_pass(raw_pass)
.render_area(render_area)
.clear_values(&vk_clear_values)
.framebuffer(raw_framebuffer);
let mut vk_attachment_info = if caps.imageless_framebuffers {
Some(
vk::RenderPassAttachmentBeginInfo::builder()
.attachments(&vk_image_views)
.build(),
)
Some(vk::RenderPassAttachmentBeginInfo::default().attachments(&vk_image_views))
} else {
None
};
Expand Down Expand Up @@ -854,21 +834,21 @@ impl crate::CommandEncoder for super::CommandEncoder {
}

unsafe fn insert_debug_marker(&mut self, label: &str) {
if let Some(ext) = self.device.debug_messenger() {
if let Some(ext) = self.device.extension_fns.debug_utils.as_ref() {
let cstr = self.temp.make_c_str(label);
let vk_label = vk::DebugUtilsLabelEXT::builder().label_name(cstr).build();
let vk_label = vk::DebugUtilsLabelEXT::default().label_name(cstr);
unsafe { ext.cmd_insert_debug_utils_label(self.active, &vk_label) };
}
}
unsafe fn begin_debug_marker(&mut self, group_label: &str) {
if let Some(ext) = self.device.debug_messenger() {
if let Some(ext) = self.device.extension_fns.debug_utils.as_ref() {
let cstr = self.temp.make_c_str(group_label);
let vk_label = vk::DebugUtilsLabelEXT::builder().label_name(cstr).build();
let vk_label = vk::DebugUtilsLabelEXT::default().label_name(cstr);
unsafe { ext.cmd_begin_debug_utils_label(self.active, &vk_label) };
}
}
unsafe fn end_debug_marker(&mut self) {
if let Some(ext) = self.device.debug_messenger() {
if let Some(ext) = self.device.extension_fns.debug_utils.as_ref() {
unsafe { ext.cmd_end_debug_utils_label(self.active) };
}
}
Expand Down
Loading

0 comments on commit 09d3daf

Please sign in to comment.