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

Implement indirect draw validation #7140

Merged
merged 8 commits into from
Mar 26, 2025

Conversation

teoxoy
Copy link
Member

@teoxoy teoxoy commented Feb 14, 2025

Connections
Closes #2431.

Description
Implements indirect draw validation by batching draw calls and injecting a compute pass prior to the render pass that will validate the indirect args.

NOTES

Testing
Added new tests, probably not enough, there are lots of possible permutations. I looked at branch coverage and most branches are tested at least.

The commits are self contained and so the PR doesn't need to be squashed.

@teoxoy teoxoy requested a review from a team as a code owner February 14, 2025 17:25
@teoxoy teoxoy force-pushed the indirect-draw-validation branch 2 times, most recently from d12fe5a to 1373962 Compare February 14, 2025 17:34
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 think my only overarching comment would be - I wonder if we can somehow internalize the cfgs in some way so that we don't need to have them all over the codebase.

I also worry about the non-indirect buffer pass starting to fail to compile and us not noticing WebGL2 compiles without it.

Comment on lines 655 to 585
hal::PipelineError::Device(error) => {
CreateComputePipelineError::Device(DeviceError::from_hal(error))
}
hal::PipelineError::Linkage(_stages, msg) => CreateComputePipelineError::Internal(msg),
hal::PipelineError::EntryPoint(_stage) => CreateComputePipelineError::Internal(
crate::device::ENTRYPOINT_FAILURE_ERROR.to_string(),
),
hal::PipelineError::PipelineConstants(_, error) => {
CreateComputePipelineError::PipelineConstants(error)
}
Copy link
Member

Choose a reason for hiding this comment

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

Thought: could these be in some kind of From implementation?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think we should, device errors in hal::PipelineError::Device need to go through device.handle_hal_error() unless there is no device yet (in this case). A From impl would be easy to misuse.

I think at some point we should coalesce the Linkage and EntryPoint variants though.

@teoxoy teoxoy force-pushed the indirect-draw-validation branch 3 times, most recently from a3b3a0f to b17487d Compare February 24, 2025 16:02
@teoxoy
Copy link
Member Author

teoxoy commented Feb 24, 2025

I ended up removing the indirect-validation feature, see last commit.

@teoxoy teoxoy force-pushed the indirect-draw-validation branch from c5bbf04 to f7b7d51 Compare February 24, 2025 17:02
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.

Discussed some feedback in call

@teoxoy teoxoy force-pushed the indirect-draw-validation branch 2 times, most recently from 30b2a00 to 329b538 Compare February 25, 2025 14:47
@teoxoy teoxoy requested a review from cwfitzgerald February 25, 2025 19:03
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.

Tests look fabulous, have some comments and a note about structure and naming, but I like the current way of dealing with shaders, at least for now.

@teoxoy teoxoy force-pushed the indirect-draw-validation branch 4 times, most recently from 5917833 to 50a78af Compare February 28, 2025 12:45
@teoxoy teoxoy requested a review from cwfitzgerald February 28, 2025 12:45
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.

Basically there, some style comments.

Comment on lines 279 to 282
for index in batches
.values()
.map(|batch| batch.metadata_resource_index)
.filter(|index| buffer_index_set.insert(*index))
Copy link
Member

Choose a reason for hiding this comment

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

Could we do these as early-continues in the for loop - as we're iterating already, I think it would read more clearly

Copy link
Member Author

Choose a reason for hiding this comment

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

Related: I was worried about those manual .clear() calls. I added 2 new data structures to get rid of the possibility of forgetting to do things in the right order.

Let me know what you think!

let vertex_or_index_count = src[src_base_offset + 0];

{
let can_overflow = ((metadata.dst_offset >> 30) & 1u) == 1u;
Copy link
Member

Choose a reason for hiding this comment

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

this would be a bit clearer using extractBits - if you don't want to use it for performance reasons, maybe a free function?

Copy link
Member Author

Choose a reason for hiding this comment

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

The backends add some validation code for extractBits to cap the offset and count. I'll add a function.

@teoxoy teoxoy force-pushed the indirect-draw-validation branch from 50a78af to 017a071 Compare March 6, 2025 18:16
@teoxoy teoxoy requested a review from cwfitzgerald March 6, 2025 20:46
@teoxoy teoxoy force-pushed the indirect-draw-validation branch from fe4bbbf to d5960bf Compare March 6, 2025 20:49
@cwfitzgerald cwfitzgerald mentioned this pull request Mar 14, 2025
6 tasks
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 have one main question, but I don't think we should block on it.

This is awesome!

@teoxoy teoxoy force-pushed the indirect-draw-validation branch from d5960bf to 74dc697 Compare March 26, 2025 17:40
teoxoy added 2 commits March 26, 2025 18:40
…TION_INDIRECT_CALL`.

With the only caveat that device creation will now panic if the `wgsl` feature is not enabled, `InstanceFlags::VALIDATION_INDIRECT_CALL` is set and the device supports `DownlevelFlags::INDIRECT_EXECUTION`.
@teoxoy teoxoy merged commit 9a2b5fd into gfx-rs:trunk Mar 26, 2025
37 checks passed
@teoxoy teoxoy deleted the indirect-draw-validation branch March 26, 2025 18:26
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.

Ensure safety of indirect draw/dispatch
2 participants