Skip to content

Remove gpu-descriptor dependency by inlining the crate - #9078

Closed
a1phyr wants to merge 11 commits into
gfx-rs:trunkfrom
a1phyr:remove-gpu-descriptor
Closed

Remove gpu-descriptor dependency by inlining the crate#9078
a1phyr wants to merge 11 commits into
gfx-rs:trunkfrom
a1phyr:remove-gpu-descriptor

Conversation

@a1phyr

@a1phyr a1phyr commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

Description

Stop depending on gpu-descriptor and inline the part of their code that we need directly.

gpu-descriptor is very passively maintained and has outdated dependencies. Inlining the crate into wgpu-hal prevents this and simplifies our code at a small cost (~300 LoC). Additionally, this should reduce compile times a bit.

Each commit can be reviewed independently. The first commit bring parts of gpu-descriptor and gpu-descriptor-types in wgpu-hal/src/vulkan/descriptor.rs and does minor import changes to accommodate for this. Other are refactoring that take advantage of the inlining.

Testing
Ran tests

Squash or Rebase?

Rebase

Checklist

  • Run cargo fmt.
  • Run taplo format.
  • Run cargo clippy --tests. If applicable, add:
    • --target wasm32-unknown-unknown
  • Run cargo xtask test to run tests.
  • If this contains user-facing changes, add a CHANGELOG.md entry.

@inner-daemons inner-daemons left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

So I'm no lawyer but if this is a line-for-line copy, that seems slightly legally dubious. More specifically, we will almost certainly need to bundle the copyright notice and license text, which it doesn't look like you did here. Overall, I'm not sure why we need this but I'll let another Mozillan handle it, since they have a whole system for these things.

Also, I realize this is an early review, and you might be in the middle of fixing the copyright fun business.

@a1phyr
a1phyr force-pushed the remove-gpu-descriptor branch from ad76441 to 3ee67e4 Compare February 19, 2026 11:23
@a1phyr

a1phyr commented Feb 19, 2026

Copy link
Copy Markdown
Contributor Author

Well, from the MIT license:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

Which I did in wgpu-hal/src/vulkan/descriptor.rs. Also, wgpu is also licensed under MIT/APACHE, so the license is bundled. Am I missing something?

@cwfitzgerald

cwfitzgerald commented Feb 19, 2026

Copy link
Copy Markdown
Member

On licensing, yeah this is fine, the one note would be to make the LICENSE field of wgpu-hal "(MIT OR Apache-2.0) AND MIT" to be fully formally correct.

@a1phyr

a1phyr commented Feb 20, 2026

Copy link
Copy Markdown
Contributor Author

Well gpu-descriptor is also "MIT OR Apache-2.0" and Apache-2.0 is pretty much the same as MIT about redistribution (keep attribution and license) so I think that it is fine as is?

On another note, do you know why some Metal tests are failing? I didn't touch this backend at all.

@inner-daemons inner-daemons left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Preliminary review.

I'm curious, what's necessarily the goal here? Is there a reason we need to remove the dependency? And if we do remove the dependency, why not just rewrite the logic as needed? It seems like copying the code over left us with some unnecessary artifacts.

Anyway, thanks for the work put in here. I'm gonna probably just gonna defer to the next reviewer for most stuff.

Comment thread wgpu-hal/src/vulkan/descriptor.rs Outdated
};

if pool_size == Default::default() {
pool_size.sampler = 1;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What's this for?

@a1phyr a1phyr Feb 27, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't know. Maybe to prevent zero-sized pools?

Comment thread wgpu-hal/src/vulkan/descriptor.rs Outdated
Comment thread wgpu-hal/src/vulkan/descriptor.rs Outdated
Comment thread wgpu-hal/src/vulkan/descriptor.rs Outdated
Comment thread wgpu-hal/src/vulkan/descriptor.rs Outdated
.max(minimal_set_count) // at least enough for allocation
.max(self.total.min(MAX_SETS)) // at least as much as was allocated so far capped to MAX_SETS
.checked_next_power_of_two() // rounded up to nearest 2^N
.unwrap_or(i32::MAX as u32);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This seems sketchy, plus shouldn't it be i32::MAX as u32 + 1 either way?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, probably (this branch was not reachable anyway). Replaced this code by a much more readable clamp. Not sure about what the next_power_of_two() is about though.

.checked_next_power_of_two() // rounded up to nearest 2^N
.unwrap_or(i32::MAX as u32);

max_sets = (u32::MAX / self.size.sampler.max(1)).min(max_sets);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This definitely needs a comment explainign what its doing dividing by the descriptor count.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Well probably, but I can't really explain it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's to avoid overflowing count * max_sets calculations below.

Comment thread wgpu-hal/src/vulkan/descriptor.rs Outdated
@a1phyr
a1phyr force-pushed the remove-gpu-descriptor branch from 1af5b40 to 7a6ac42 Compare February 27, 2026 13:08
@a1phyr
a1phyr force-pushed the remove-gpu-descriptor branch from 7a6ac42 to 93a0882 Compare February 27, 2026 13:14
@a1phyr

a1phyr commented Feb 27, 2026

Copy link
Copy Markdown
Contributor Author

I'm curious, what's necessarily the goal here? Is there a reason we need to remove the dependency?

Well, mainly the fact that it's not really maintained. Also this enables us to tailor fit this code.

And if we do remove the dependency, why not just rewrite the logic as needed? It seems like copying the code over left us with some unnecessary artifacts.

This is what I started with some low-hanging fruits in commits after the first, but looks that I missed some.

@a1phyr
a1phyr force-pushed the remove-gpu-descriptor branch from 93a0882 to 1a787ab Compare February 27, 2026 13:17
@a1phyr
a1phyr force-pushed the remove-gpu-descriptor branch from 1a787ab to 4b83123 Compare February 27, 2026 14:06
@a1phyr

a1phyr commented Mar 2, 2026

Copy link
Copy Markdown
Contributor Author

CI failure is a DX12 timeout, so probably unrelated.

@teoxoy teoxoy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I found some more improvements/simplifications and decided to implement the allocator from scratch (#9161). I think it ended up better suited to our Vulkan backend (using knowledge of BGL creation/destruction). A new implementation also avoids the question of how do we make sure we comply with the license brought up at the maintainers meeting last week (we talked about it but didn't come to a resolution).

}
}
unsafe { self.raw.create_descriptor_pool(&vk_info, None) }
.map_err(super::map_host_device_oom_err)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This won't handle vk::Result::ERROR_FRAGMENTATION which is a valid error type for this cmd to return. We can probably just map it to an OOM error for now.

Err(DeviceAllocationError::Unexpected)
}
}
.map_err(super::map_host_device_oom_err)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This one needs to additionally handle ERROR_FRAGMENTED_POOL (note that this one is different from ERROR_FRAGMENTATION) & ERROR_OUT_OF_POOL_MEMORY. Mapping them to an OOM error is probably fine.

///
/// Pool must be created from this device.
unsafe fn alloc_descriptor_sets<'a>(
unsafe fn alloc_descriptor_sets(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should now be alloc_descriptor_set and can return a single vk::DescriptorSet. The docs also need updating.

fn handle_unexpected(err: vk::Result) -> ! {
pub(super) fn handle_unexpected(err: vk::Result) -> ! {
panic!("Unexpected Vulkan error: `{err}`")
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We shouldn't need to use this function anymore.

.checked_next_power_of_two() // rounded up to nearest 2^N
.unwrap_or(i32::MAX as u32);

max_sets = (u32::MAX / self.size.sampler.max(1)).min(max_sets);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's to avoid overflowing count * max_sets calculations below.

.ok()
.is_some_and(|count| count <= bucket.total));

unsafe { bucket.free(device, self.raw_sets_cache.drain(..), set.pool_id) };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

raw_sets_cache seems unnecessary.

}

if let Some(last_id) = last {
unsafe { bucket.free(device, self.raw_sets_cache.drain(..), last_id) };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We only ever allocate one set at a time, this looks like dead code.

github-merge-queue Bot pushed a commit to petgraph/petgraph that referenced this pull request Mar 8, 2026
Together with gfx-rs/wgpu#9078, this should
deduplicate hashbrown for wgpu and eventually for Ruffle.

Co-authored-by: Tomáš Procházka <SuchAFuriousDeath@users.noreply.github.com>
@inner-daemons

Copy link
Copy Markdown
Collaborator

@a1phyr Just FYI, this is likely to be replaced by #9161 unless something goes horribly wrong.

@a1phyr

a1phyr commented Mar 17, 2026

Copy link
Copy Markdown
Contributor Author

Yeah, this is what I figured out, this is why I didn't answer to the last reviews.

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.

4 participants