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

Add multi draw indirect feature #2315

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rconde01
Copy link
Contributor

@rconde01 rconde01 commented Nov 16, 2021

This PR adds a multi-draw-indirect feature and is meant to replace #1949

It is rebased over the now merged #2022

Fixes #1354

spec/index.bs Outdated Show resolved Hide resolved
@github-actions
Copy link
Contributor

Previews, as seen when this build job started (b073087):
WebGPU | IDL
WGSL
Explainer

Copy link
Contributor

@kvark kvark left a comment

Choose a reason for hiding this comment

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

Thank you!

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
@AmesingFlank
Copy link

Hey! Any updates on this? Can we expect this feature to be available in v1.0?

@kainino0x
Copy link
Contributor

Since this is an optional feature I don't think it will be a blocking feature for V1 release. After V1 this will be a living spec, and we'll be doing incremental additions like this one (there won't be a wait for a V1.1 or V2).

@kainino0x kainino0x added this to the Polish post-V1 milestone May 3, 2022
@kainino0x
Copy link
Contributor

Briefly discussed in meeting: We're going to keep this in polish post-v1, won't be able to spend the time to get it into the spec for V1. Will be soon after. Sorry to folks waiting for this!

@kainino0x kainino0x marked this pull request as draft September 22, 2022 16:16
@kainino0x kainino0x modified the milestones: Polish post-V1, Milestone 2? Aug 15, 2023
@rconde01
Copy link
Contributor Author

@kainino0x We would like to restart this discussion based on your comment above. We're happy to assist in any investigations required to move this forward.

@kainino0x
Copy link
Contributor

Let me propose this for Milestone 1 and add it to the agenda. Unfortunately we don't have a meeting this week, but hopefully next week (in the Pacific-timed meeting).

@kainino0x kainino0x modified the milestones: Polish post-V1, Milestone 0, Milestone 1 Oct 24, 2023
@rconde01
Copy link
Contributor Author

Sounds good.

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated Show resolved Hide resolved
Draws primitives using an array of parameters read from a {{GPUBuffer}}.
See [[#rendering-operations]] for the detailed specification.

This method is defined if and only if the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
Copy link
Contributor

@kainino0x kainino0x Oct 24, 2023

Choose a reason for hiding this comment

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

I think this is the check I was missing above.

Just an editorial thing but we'll need to move this to a content-timeline check that throws "TypeError" if the feature isn't enabled, as WebIDL doesn't let us dynamically decide whether to define something or not.

spec/index.bs Outdated Show resolved Hide resolved
spec/index.bs Outdated
optional GPUSize64 drawCountOffset = 0);
undefined multiDrawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset,
GPUSize32 maxDrawCount,
optional GPUBuffer drawCountBuffer = null,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit for editors: need to check if these GPUBuffers need to be nullable

@kainino0x
Copy link
Contributor

kainino0x commented Oct 24, 2023

If you make revisions on this PR, feel free to not deal with doing a rebase (though you can if you want to). We can deal with it later.

@rconde01 rconde01 force-pushed the add-multi-draw-indirect-feature branch from 4b20359 to a58d222 Compare October 25, 2023 18:02
@rconde01
Copy link
Contributor Author

@kainino0x I think the feedback is addressed. I was able to do the rebase, but some of the editor notes got stomped.

@@ -1828,6 +1828,12 @@ A <dfn dfn>supported limits</dfn> object has a value for every limit defined by
<tr class=row-continuation><td colspan=4>
The maximum value for the arguments of
{{GPUComputePassEncoder/dispatchWorkgroups(workgroupCountX, workgroupCountY, workgroupCountZ)}}.

<tr><td><dfn>maxMultiDrawIndirectCount</dfn>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A few thoughts here:

  • Shouldn't this also apply to the value in the drawCountBuffer?
  • Does this mean that after enabling the feature you still need to request a higher limit or else will be stuck to 1? It's workable but seems a bit weird.
  • Seems a bit weird that this could be 1 when the feature is not enabled. In fact it seems weird the limit exists at all when the feature isn't enabled...I don't think there precedent for feature related limits though.
  • @kvark had suggested in a previous comment to " lift the limit entirely...I.e. it becomes limited in the same way as maximum index count is limited." It's not clear to me how "maximum index count is limited", other than it's tied to the max buffer size. Maybe the feature should only be available when the implementation max count is >= maxStorageBufferBindingSize and then this limit goes away? Not sure how reasonable that is.

Copy link
Contributor Author

@rconde01 rconde01 Oct 26, 2023

Choose a reason for hiding this comment

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

Shouldn't this also apply to the value in the drawCountBuffer?

Realized this is already covered transitively since drawCountBuffer is already limited by maxDrawCount. Nm.


undefined multiDrawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset,
GPUSize32 maxDrawCount,
optional GPUBuffer drawCountBuffer = null,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

from @kainino0x: nit for editors: need to check if these GPUBuffers need to be nullable

Copy link
Contributor

Choose a reason for hiding this comment

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

To match feature parity with D3D12 and Vulkan the drawCountBuffer should be nullable, in which case maxDrawCount becomes the draw count.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the question was about optional vs nullable

The <dfn dfn for=>indirect multiDraw parameters</dfn> encoded in the |indirectBuffer| must be zero or more
tightly packed blocks of **four 32-bit unsigned integer values (16 bytes total)**, given in the same
order as the arguments for {{GPURenderCommandsMixin/draw()}}. For example:

Copy link
Contributor

Choose a reason for hiding this comment

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

we should call out here that indirect-first-instance is not required to use firstInstance here, since it is not obvious.

The <dfn dfn for=>indirect multiDrawIndexed parameters</dfn> encoded in the |indirectBuffer| must be zero or more
tightly packed blocks of **five 32-bit unsigned integer values (20 bytes total)**, given in
the same order as the arguments for {{GPURenderCommandsMixin/drawIndexed()}}. For example:

Copy link
Contributor

Choose a reason for hiding this comment

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

same

@kainino0x
Copy link
Contributor

^ just dropping some editorial notes for when we pick up this PR again

- |drawCountOffset| + sizeof([=indirect multiDraw count=]) &le;
|drawCountBuffer|.{{GPUBuffer/[[size]]}}.
- |drawCountOffset| is a multiple of 4.
</div>

Choose a reason for hiding this comment

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

When implementing this for D3D12, the driver / validation layer checks if maxDrawCount exceeds the range of the indirect buffer. Specifically it returns E_INVALIDARG when closing the command list. We should add this to the validation. Something along the lines of: indirectOffset + sizeof(indirectDrawParams) * maxDrawCount should not be out of bounds of indirectBuffer

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

Successfully merging this pull request may close these issues.

DrawIndirectCount
6 participants