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

Degenerification part 1/3: wgpu-hal DynDevice & friends #6098

Closed
wants to merge 43 commits into from

Conversation

Wumpf
Copy link
Member

@Wumpf Wumpf commented Aug 10, 2024

Connections

Description
Introduces a new Dyn "backend" which uses dynamic dispatch & std::any::Any based casting while keeping changes to wgpu-core as minimal as possible.

Note that casts through Any could be avoided altogether, but right now part2 of the series relies on standard any casts, so I'd advocate to keep this as a future improvement.
Internal unboxing mechanism as proposed by @cwfitzgerald however sidesteps Any for the most part (except for debug assertion) which allows us to keep wgpu-hal backend unchanged for the most part which profits their isolation & direct consumers of wgpu-hal. Concrete, this means that destroy methods continue to consume objects via move (which is both semantically & syntactically convenient).
Also note that this is intentionally not exposed as part of the public interface.

Speaking of future improvements:
Something that has been discussed in the maintainer group previously while this was already under way is to use enum based DynResource which would allow to trivially know the size of each resource and instead dispatch via match.
This PR series sticks with Box and Any in favor of expedience but is my belief that such refactors will be easier once this lands!

Commits have been cleaned up as good as possible to make them digestable for review, but there might be still some slight meandering in there hinting at earlier experimentations.

Testing

Checklist

  • Run cargo fmt.
  • Run cargo clippy. If applicable, add:
    • --target wasm32-unknown-unknown
    • --target wasm32-unknown-emscripten
  • Run cargo xtask test to run tests.
  • [ ] Add change to CHANGELOG.md. See simple instructions inside file. changelog in Part 3

@ErichDonGubler
Copy link
Member

I'll commit to this first part in the next couple of days. 😀

Copy link
Contributor

@nical nical left a comment

Choose a reason for hiding this comment

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

Amazing

Copy link
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

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

I don't see anything that should block this

ErichDonGubler

This comment was marked as resolved.

@ErichDonGubler
Copy link
Member

To be clear: I also see nothing blocking so far. 👏🏻

@Wumpf
Copy link
Member Author

Wumpf commented Aug 14, 2024

merged in part 3

@Wumpf Wumpf closed this Aug 14, 2024
Copy link
Member

@ErichDonGubler ErichDonGubler left a comment

Choose a reason for hiding this comment

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

LGTM; really the only issue I noticed is that we don't have any docs for most of this. Buuut 🤷🏻‍♂️ I think it's better to defer to an issue, rather than block here and keep merge conflicts between this and probably most other PRs in total limbo.

Comment on lines 5 to 37
pub trait DynCommandEncoder {
unsafe fn set_index_buffer<'a>(
&mut self,
binding: BufferBinding<'a, dyn DynBuffer>,
format: wgt::IndexFormat,
);

unsafe fn set_vertex_buffer<'a>(
&mut self,
index: u32,
binding: BufferBinding<'a, dyn DynBuffer>,
);
}

impl<C: CommandEncoder> DynCommandEncoder for C {
unsafe fn set_index_buffer<'a>(
&mut self,
binding: BufferBinding<'a, dyn DynBuffer>,
format: wgt::IndexFormat,
) {
let binding = binding.expect_downcast();
unsafe { self.set_index_buffer(binding, format) };
}

unsafe fn set_vertex_buffer<'a>(
&mut self,
index: u32,
binding: BufferBinding<'a, dyn DynBuffer>,
) {
let binding = binding.expect_downcast();
unsafe { self.set_vertex_buffer(index, binding) };
}
}
Copy link
Member

Choose a reason for hiding this comment

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

issue: We don't document a safety contract or adherence thereto. We should do this.

C::end_debug_marker(self);
}
}

unsafe fn set_index_buffer<'a>(
Copy link
Member

Choose a reason for hiding this comment

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

issue: We don't document a safety contract or adherence thereto for these methods. We should do this.

use super::DynBuffer;
use super::{DynBuffer, DynResourceExt as _};

pub trait DynCommandEncoder: std::fmt::Debug {
Copy link
Member

Choose a reason for hiding this comment

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

issue: We don't document a safety contract or adherence thereto for these methods. We should do this.

Comment on lines 5 to 13
pub trait DynDevice {
unsafe fn destroy_buffer(&self, buffer: Box<dyn DynBuffer>);
}

impl<D: Device> DynDevice for D {
unsafe fn destroy_buffer(&self, buffer: Box<dyn DynBuffer>) {
unsafe { D::destroy_buffer(self, buffer.unbox()) };
}
}
Copy link
Member

Choose a reason for hiding this comment

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

issue: We don't document a safety contract or adherence thereto for these methods. We should do this.

pub suboptimal: bool,
}

pub trait DynSurface: DynResource {
Copy link
Member

Choose a reason for hiding this comment

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

issue: We don't document a safety contract or adherence thereto for these methods. We should do this.


use super::DynResourceExt as _;

pub trait DynQueue: DynResource {
Copy link
Member

Choose a reason for hiding this comment

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

issue: We don't document a safety contract or adherence thereto for these methods. We should do this.

Comment on lines +1 to +3
// Box casts are needed, alternative would be a temporaries which are more verbose and not more expressive.
#![allow(trivial_casts)]

Copy link
Member

Choose a reason for hiding this comment

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

suggestion: This is actually not necessary; the offending lines of code can be fixed thusly:

-            .map(|b| Box::new(b) as Box<dyn DynCommandEncoder>)
+            .map(|b| -> Box<dyn DynCommandEncoder> { Box::new(b) })

Will push a fix myself anon.

}

pub trait DynInstance: DynResource {
unsafe fn create_surface(
Copy link
Member

Choose a reason for hiding this comment

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

issue: We don't document a safety contract or adherence thereto for these methods. We should do this.

@Wumpf Wumpf deleted the degenerification-part1 branch August 14, 2024 16:49
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.

5 participants