Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade ash to 0.38 and egui to 0.27.2 #10

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

YouSafe
Copy link
Contributor

@YouSafe YouSafe commented Nov 12, 2023

Fix #9

Copy link

@MarijnS95 MarijnS95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of these calls aren't contributing to safety: refer to the Ash README on the latest published version.

let wait_dst_stage_mask = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
self.device.queue_submit(
self.graphics_queue,
&[vk::SubmitInfo::builder()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from_ref?

.image_indices(&[image_index as u32])
.wait_semaphores(&[self.render_finished_semaphores[self.current_frame]]),
.swapchains(std::slice::from_ref(&self.swapchain))
.image_indices(&image_indices)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw the temporary allocation here is fine, as long as you don't call .build.

let wait_dst_stage_mask = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
self.device.queue_submit(
self.graphics_queue,
&[vk::SubmitInfo::builder()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again from_ref might help to remove .build(). Constructing slices inside the same expression is fine.

}
.expect("Failed to create descriptor pool.");
let descriptor_pool = {
let pool_sizes = [vk::DescriptorPoolSize::builder()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No wins in factoring this out either.

let subpasses = [vk::SubpassDescription::builder()
.pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS)
.color_attachments(&color_attachment_refs)
.build()];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the lifetime of &color_attachments_refs gets lost.

@MatchaChoco010
Copy link
Owner

First of all, thanks for the PR!

Sorry, but the PR seems to contain things that don't necessarily contribute to safety, as @MarijnS95 points out.
I know it's hard because the issue of lifetime and raw pointer is quite a difficult one, but @YouSafe could you please fix this PR?

@MarijnS95
Copy link

MarijnS95 commented Nov 18, 2023

For what it is worth some older Ash docs recommended (iirc) the &[...build()] pattern, as long as it resides inside the function-call statement because individual expression results are only dropped at the end of an expression (at the ;).

As such there are a few ways to go at this PR and these changes; but for the time being I'd recommend either tackling everything or only fix the actual lifetime issues (and not introduce any new ones!).

When .build() is removed in Ash 0.38 these temporary &[] borrows of local arrays are once again fine and safe (and the borrow checker will tell you to refactor when they're not) so it isn't worth replacing them all with slice::from_ref(). Removing .build() now however requires all those to be replaced with slice::from_ref(&) "temporarily" (and that doesn't work for >1 items).

@MarijnS95
Copy link

The ash 0.38 release is out, which now no longer has these safety issues when using the builder pattern. build() can no longer be called.

@YouSafe YouSafe changed the title Fix undefined behaviour Upgrade ash to 0.38 and egui to 0.27.2 Apr 5, 2024
@YouSafe
Copy link
Contributor Author

YouSafe commented Apr 5, 2024

Thank you for your work on ash 0.38, @MarijnS95!

Here are some notes on this PR:

  • I was unable to upgrade ash alone without also upgrading egui and, consequently, winit because of version mismatch issues with raw-window-handle.
  • Since the PR for the ash upgrade for gpu-allocator has not yet been merged, I temporarily specified the branch of the PR as a dependency here.
  • There are still sync validation errors which I'm not sure if there were present before the upgrade.
  • I think the wrong color space is being used for the examples, but that is not a new issue introduced by this PR.

I have some questions if that is okay with you, @MarijnS95:

  • I've used std::slice::from_ref in two places in integration.rs where it would otherwise give the following error: creates a temporary value which is freed while still in use. Is that okay?
  • Do you think it is okay that I used this kind of import: use ash::ext::debug_utils::Instance as DebugUtils; or would you strongly advise against that?

@YouSafe
Copy link
Contributor Author

YouSafe commented Apr 5, 2024

I ran the current version on the main branch and can confirm that the sync issues were present before this PR.

@MarijnS95
Copy link

  • I think the wrong color space is being used for the examples, but that is not a new issue introduced by this PR.

Without diving in this codebase, this might be a common problem where the first format from swapchain' capabilities is used. If this is BGR instead of RGB, the render target bind point might not be updated and hence swizzle the wrong colors on write (though the validation layer should complain here).

  • I've used std::slice::from_ref in two places in integration.rs where it would otherwise give the following error: creates a temporary value which is freed while still in use. Is that okay?

slice::from_ref is still something that we recommend for more idiomatic code.

  • Do you think it is okay that I used this kind of import: use ash::ext::debug_utils::Instance as DebugUtils; or would you strongly advise against that?

I'd recommend to use ash::{vk, ext, ...} and reference this as ext::debug_utils::Instance. That makes it less confusing especially when you also want to use ext::debug_utils::Device to e.g. place markers on a command buffer.

Comment on lines +1229 to +1235
.dependencies(&[vk::SubpassDependency::default()
.src_subpass(vk::SUBPASS_EXTERNAL)
.dst_subpass(0)
.src_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE)
.dst_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE)
.src_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT)
.dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT)
.build()]),
.dst_stage_mask(vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT)]),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fyi for POD structs without references (pointers to objects or arrays), especially when you fill all fields like this, are cleaner to write with plain Rust field syntax (than the builder pattern). Same for vk::AttachmentDescription above, vk::ImageSubresourceRange and probably a few others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Undefined behaviour in library
3 participants