Skip to content

Commit b80d5d9

Browse files
committed
Extract multi-draw-indirect into new methods.
1 parent c16910b commit b80d5d9

File tree

1 file changed

+151
-57
lines changed

1 file changed

+151
-57
lines changed

spec/index.bs

Lines changed: 151 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,12 @@ The default is used if a value is not explicitly specified in {{GPUDeviceDescrip
12541254
<tr class=row-continuation><td colspan=4>
12551255
The maximum value for the arguments of {{GPUComputePassEncoder/dispatch(x, y, z)}}.
12561256

1257+
<tr><td><dfn>maxMultiDrawIndirectCount</dfn>
1258+
<td>{{GPUSize32}} <td>Higher <td>1
1259+
<tr class=row-continuation><td colspan=4>
1260+
The maximum value for the `maxDrawCount` argument in
1261+
{{GPURenderEncoderBase/multiDrawIndirect()}} and {{GPURenderEncoderBase/multiDrawIndexedIndirect()}}.
1262+
12571263
</table>
12581264

12591265
Issue: Do we need to have a max per-pixel render target size?
@@ -1290,6 +1296,7 @@ interface GPUSupportedLimits {
12901296
readonly attribute unsigned long maxComputeWorkgroupInvocations;
12911297
readonly attribute GPUExtent3D maxComputeWorkgroupSize;
12921298
readonly attribute unsigned long maxComputePerDimensionDispatchSize;
1299+
readonly attribute unsigned long maxIndirectDrawCount;
12931300
};
12941301
</script>
12951302

@@ -6689,12 +6696,15 @@ interface mixin GPURenderEncoderBase {
66896696
optional GPUSignedOffset32 baseVertex = 0,
66906697
optional GPUSize32 firstInstance = 0);
66916698

6692-
undefined drawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset,
6693-
optional GPUSize32 maxDrawCount = 1,
6699+
undefined drawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
6700+
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset);
6701+
6702+
undefined multiDrawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset,
6703+
GPUSize32 maxDrawCount,
66946704
optional GPUBuffer drawCountBuffer = null,
66956705
optional GPUSize64 drawCountOffset = 0);
6696-
undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset,
6697-
optional GPUSize32 maxDrawCount = 1,
6706+
undefined multiDrawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset,
6707+
GPUSize32 maxDrawCount,
66986708
optional GPUBuffer drawCountBuffer = null,
66996709
optional GPUSize64 drawCountOffset = 0);
67006710
};
@@ -7216,12 +7226,12 @@ enum GPUStoreOp {
72167226
</div>
72177227
</div>
72187228

7219-
: <dfn>drawIndirect(indirectBuffer, indirectOffset, maxDrawCount, drawCountBuffer, drawCountOffset)</dfn>
7229+
: <dfn>drawIndirect(indirectBuffer, indirectOffset)</dfn>
72207230
::
72217231
Draws primitives using parameters read from a {{GPUBuffer}}.
72227232
See [[#rendering-operations]] for the detailed specification.
72237233

7224-
The <dfn dfn for=>indirect draw parameters</dfn> encoded in the |indirectBuffer| must be a tightly
7234+
The <dfn dfn for=>indirect draw parameters</dfn> encoded in the buffer must be a tightly
72257235
packed block of **four 32-bit unsigned integer values (16 bytes total)**, given in the same
72267236
order as the arguments for {{GPURenderEncoderBase/draw()}}. For example:
72277237

@@ -7238,23 +7248,13 @@ enum GPUStoreOp {
72387248
non-zero `firstInstance` value will result in the {{GPURenderEncoderBase/drawIndirect()}} call being
72397249
treated as a no-op.
72407250

7241-
If and only if the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled, [=indirect draw parameters=]
7242-
may be repeated with 16 byte stride, allowing multiple draws per call to {{GPURenderEncoderBase/drawIndirect()}}.
7243-
The actual number of draws is the minimum of |maxDrawCount| and the [=indirect draw count=] (if given).
7244-
7245-
The <dfn dfn for=>indirect draw count</dfn> encoded in the |drawCountBuffer| must be a **32-bit unsigned
7246-
integer** giving the number of draws to issue from the |indirectBuffer|.
7247-
72487251
<div algorithm="GPURenderEncoderBase.drawIndirect">
72497252
**Called on:** {{GPURenderEncoderBase}} this.
72507253

72517254
**Arguments:**
72527255
<pre class=argumentdef for="GPURenderEncoderBase/drawIndirect(indirectBuffer, indirectOffset)">
72537256
|indirectBuffer|: Buffer containing the [=indirect draw parameters=].
72547257
|indirectOffset|: Offset in bytes into |indirectBuffer| where the drawing data begins.
7255-
|maxDrawCount|: Maxumum number of draws or exact number of draws if |drawCountBuffer| is `null`.
7256-
|drawCountBuffer|: Buffer containing the [=indirect draw count=].
7257-
|drawCountOffset|: Offset in bytes into |drawCountBuffer| where the [=indirect draw count=] is located.
72587258
</pre>
72597259

72607260
**Returns:** {{undefined}}
@@ -7269,24 +7269,17 @@ enum GPUStoreOp {
72697269
- |indirectOffset| + sizeof([=indirect draw parameters=]) &le;
72707270
|indirectBuffer|.{{GPUBuffer/[[size]]}}.
72717271
- |indirectOffset| is a multiple of 4.
7272-
- |maxDrawCount| = 1, unless the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
7273-
- |drawCountBuffer| is `null`, unless the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
7274-
- |drawCountBuffer| is [$valid to use with$] |this|.
7275-
- |drawCountBuffer|.{{GPUBuffer/[[usage]]}} contains {{GPUBufferUsage/INDIRECT}}.
7276-
- |drawCountOffset| + sizeof([=indirect draw count=]) &le;
7277-
|drawCountBuffer|.{{GPUBuffer/[[size]]}}.
7278-
- |drawCountOffset| is a multiple of 4.
72797272
</div>
7280-
1. Add |indirectBuffer| and |drawCountBuffer| (if given) to the [=usage scope=] as [=internal usage/input=].
7273+
1. Add |indirectBuffer| to the [=usage scope=] as [=internal usage/input=].
72817274
</div>
72827275
</div>
72837276

7284-
: <dfn>drawIndexedIndirect(indirectBuffer, indirectOffset, maxDrawCount, drawCountBuffer, drawCountOffset)</dfn>
7277+
: <dfn>drawIndexedIndirect(indirectBuffer, indirectOffset)</dfn>
72857278
::
72867279
Draws indexed primitives using parameters read from a {{GPUBuffer}}.
72877280
See [[#rendering-operations]] for the detailed specification.
72887281

7289-
The <dfn dfn for=>indirect drawIndexed parameters</dfn> encoded in the |indirectBuffer| must be a
7282+
The <dfn dfn for=>indirect drawIndexed parameters</dfn> encoded in the buffer must be a
72907283
tightly packed block of **five 32-bit unsigned integer values (20 bytes total)**, given in
72917284
the same order as the arguments for {{GPURenderEncoderBase/drawIndexed()}}. For example:
72927285

@@ -7304,23 +7297,13 @@ enum GPUStoreOp {
73047297
non-zero `firstInstance` value will result in the {{GPURenderEncoderBase/drawIndirect()}} call being
73057298
treated as a no-op.
73067299

7307-
If and only if the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled, [=indirect draw parameters=]
7308-
may be repeated with 16 byte stride, allowing multiple draws per call to {{GPURenderEncoderBase/drawIndirect()}}.
7309-
The actual number of draws is the minimum of |maxDrawCount| and the [=indirect draw count=] (if given).
7310-
7311-
The <dfn dfn for=>indirect drawIndexed count</dfn> encoded in the |drawCountBuffer| must be a **32-bit unsigned
7312-
integer** giving the number of draws to issue from the |indirectBuffer|.
7313-
73147300
<div algorithm="GPURenderEncoderBase.drawIndexedIndirect">
73157301
**Called on:** {{GPURenderEncoderBase}} this.
73167302

73177303
**Arguments:**
73187304
<pre class=argumentdef for="GPURenderEncoderBase/drawIndexedIndirect(indirectBuffer, indirectOffset)">
73197305
|indirectBuffer|: Buffer containing the [=indirect drawIndexed parameters=].
73207306
|indirectOffset|: Offset in bytes into |indirectBuffer| where the drawing data begins.
7321-
|maxDrawCount|: Maxumum number of draws or exact number of draws if |drawCountBuffer| is `null`.
7322-
|drawCountBuffer|: Buffer containing the [=indirect drawIndexed count=].
7323-
|drawCountOffset|: Offset in bytes into |drawCountBuffer| where the [=indirect drawIndexed count=] is located.
73247307
</pre>
73257308

73267309
**Returns:** {{undefined}}
@@ -7335,22 +7318,139 @@ enum GPUStoreOp {
73357318
- |indirectOffset| + sizeof([=indirect drawIndexed parameters=]) &le;
73367319
|indirectBuffer|.{{GPUBuffer/[[size]]}}.
73377320
- |indirectOffset| is a multiple of 4.
7338-
- |maxDrawCount| = 1, unless the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
7321+
</div>
7322+
1. Add |indirectBuffer| to the [=usage scope=] as [=internal usage/input=].
7323+
</div>
7324+
</div>
7325+
7326+
: <dfn>multiDrawIndirect(indirectBuffer, indirectOffset, maxDrawCount, drawCountBuffer, drawCountOffset)</dfn>
7327+
::
7328+
Draws primitives using an array of parameters read from a {{GPUBuffer}}.
7329+
See [[#rendering-operations]] for the detailed specification.
7330+
7331+
This method is defined if and only if the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
7332+
7333+
The <dfn dfn for=>indirect multiDraw parameters</dfn> encoded in the |indirectBuffer| must be zero or more
7334+
tightly packed blocks of **four 32-bit unsigned integer values (16 bytes total)**, given in the same
7335+
order as the arguments for {{GPURenderEncoderBase/draw()}}. For example:
7336+
7337+
<pre highlight="js">
7338+
let drawIndirectParameters = new Uint32Array(8);
7339+
// first draw
7340+
drawIndirectParameters[0] = vertexCount0;
7341+
drawIndirectParameters[1] = instanceCount0;
7342+
drawIndirectParameters[2] = firstVertex0;
7343+
drawIndirectParameters[3] = firstInstance0;
7344+
// second draw
7345+
drawIndirectParameters[4] = vertexCount1;
7346+
drawIndirectParameters[5] = instanceCount1;
7347+
drawIndirectParameters[6] = firstVertex1;
7348+
drawIndirectParameters[7] = firstInstance1;
7349+
</pre>
7350+
7351+
The <dfn dfn for=>indirect multiDraw count</dfn> encoded in the |drawCountBuffer| must be a **32-bit unsigned
7352+
integer** giving the number of draws to issue from the |indirectBuffer|.
7353+
7354+
<div algorithm="GPURenderEncoderBase.multiDrawIndirect">
7355+
**Called on:** {{GPURenderEncoderBase}} this.
7356+
7357+
**Arguments:**
7358+
<pre class=argumentdef for="GPURenderEncoderBase/multiDrawIndirect(indirectBuffer, indirectOffset, maxDrawCount, drawCountBuffer, drawCountOffset)">
7359+
|indirectBuffer|: Buffer containing the [=indirect multiDraw parameters=].
7360+
|indirectOffset|: Offset in bytes into |indirectBuffer| where the drawing data begins.
7361+
|maxDrawCount|: Maxumum number of draws or exact number of draws if |drawCountBuffer| is `null`.
7362+
|drawCountBuffer|: Buffer containing the [=indirect multiDraw count=].
7363+
|drawCountOffset|: Offset in bytes into |drawCountBuffer| where the [=indirect multiDraw count=] is located.
7364+
</pre>
7365+
7366+
**Returns:** {{undefined}}
7367+
7368+
Issue the following steps on the [=Device timeline=] of |this|.{{GPUObjectBase/[[device]]}}:
7369+
<div class=device-timeline>
7370+
1. If any of the following conditions are unsatisfied, make |this| [=invalid=] and stop.
7371+
<div class=validusage>
7372+
- It is [$valid to draw$] with |this|.
7373+
- |indirectBuffer| is [$valid to use with$] |this|.
7374+
- |indirectBuffer|.{{GPUBuffer/[[usage]]}} contains {{GPUBufferUsage/INDIRECT}}.
7375+
- |indirectOffset| + sizeof([=indirect multiDraw parameters=]) &le;
7376+
|indirectBuffer|.{{GPUBuffer/[[size]]}}.
7377+
- |indirectOffset| is a multiple of 4.
7378+
- |maxDrawCount| &le; limits.{{supported limits/maxMultiDrawIndirectCount}}.
73397379
- |drawCountBuffer| is `null`, unless the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
73407380
- |drawCountBuffer| is [$valid to use with$] |this|.
73417381
- |drawCountBuffer|.{{GPUBuffer/[[usage]]}} contains {{GPUBufferUsage/INDIRECT}}.
7342-
- |drawCountOffset| + sizeof([=indirect drawIndexed count=]) &le;
7382+
- |drawCountOffset| + sizeof([=indirect multiDraw count=]) &le;
73437383
|drawCountBuffer|.{{GPUBuffer/[[size]]}}.
73447384
- |drawCountOffset| is a multiple of 4.
73457385
</div>
73467386
1. Add |indirectBuffer| and |drawCountBuffer| (if given) to the [=usage scope=] as [=internal usage/input=].
73477387
</div>
73487388
</div>
7349-
</dl>
73507389

7351-
Note: The ability to set a `firstInstance` for indirect draw calls is initially disabled to expand
7352-
the hardware that supports WebGPU. It is likely to be added as a feature in the future along with
7353-
other new indirect drawing features.
7390+
: <dfn>multiDrawIndexedIndirect(indirectBuffer, indirectOffset, maxDrawCount, drawCountBuffer, drawCountOffset)</dfn>
7391+
::
7392+
Draws indexed primitives using an array of parameters read from a {{GPUBuffer}}.
7393+
See [[#rendering-operations]] for the detailed specification.
7394+
7395+
The <dfn dfn for=>indirect multiDrawIndexed parameters</dfn> encoded in the |indirectBuffer| must be zero or more
7396+
tightly packed blocks of **five 32-bit unsigned integer values (20 bytes total)**, given in
7397+
the same order as the arguments for {{GPURenderEncoderBase/drawIndexed()}}. For example:
7398+
7399+
<pre highlight="js">
7400+
let drawIndexedIndirectParameters = new Uint32Array(10);
7401+
// first draw
7402+
drawIndexedIndirectParameters[0] = indexCount0;
7403+
drawIndexedIndirectParameters[1] = instanceCount0;
7404+
drawIndexedIndirectParameters[2] = firstIndex0;
7405+
drawIndexedIndirectParameters[3] = baseVertex0;
7406+
drawIndexedIndirectParameters[4] = firstInstance0;
7407+
// second draw
7408+
drawIndexedIndirectParameters[5] = indexCount1;
7409+
drawIndexedIndirectParameters[6] = instanceCount1;
7410+
drawIndexedIndirectParameters[7] = firstIndex1;
7411+
drawIndexedIndirectParameters[8] = baseVertex1;
7412+
drawIndexedIndirectParameters[9] = firstInstance1;
7413+
</pre>
7414+
7415+
The <dfn dfn for=>indirect multiDrawIndexed count</dfn> encoded in the |drawCountBuffer| must be a **32-bit unsigned
7416+
integer** giving the number of draws to issue from the |indirectBuffer|.
7417+
7418+
<div algorithm="GPURenderEncoderBase.multiDrawIndexedIndirect">
7419+
**Called on:** {{GPURenderEncoderBase}} this.
7420+
7421+
**Arguments:**
7422+
<pre class=argumentdef for="GPURenderEncoderBase/multiDrawIndexedIndirect(indirectBuffer, indirectOffset, maxDrawCount, drawCountBuffer, drawCountOffset)">
7423+
|indirectBuffer|: Buffer containing the [=indirect multiDrawIndexed parameters=].
7424+
|indirectOffset|: Offset in bytes into |indirectBuffer| where the drawing data begins.
7425+
|maxDrawCount|: Maxumum number of draws or exact number of draws if |drawCountBuffer| is `null`.
7426+
|drawCountBuffer|: Buffer containing the [=indirect multiDrawIndexed count=].
7427+
|drawCountOffset|: Offset in bytes into |drawCountBuffer| where the [=indirect multiDrawIndexed count=] is located.
7428+
</pre>
7429+
7430+
**Returns:** {{undefined}}
7431+
7432+
Issue the following steps on the [=Device timeline=] of |this|.{{GPUObjectBase/[[device]]}}:
7433+
<div class=device-timeline>
7434+
1. If any of the following conditions are unsatisfied, make |this| [=invalid=] and stop.
7435+
<div class=validusage>
7436+
- It is [$valid to draw indexed$] with |this|.
7437+
- |indirectBuffer| is [$valid to use with$] |this|.
7438+
- |indirectBuffer|.{{GPUBuffer/[[usage]]}} contains {{GPUBufferUsage/INDIRECT}}.
7439+
- |indirectOffset| + sizeof([=indirect multiDrawIndexed parameters=]) &le;
7440+
|indirectBuffer|.{{GPUBuffer/[[size]]}}.
7441+
- |indirectOffset| is a multiple of 4.
7442+
- |maxDrawCount| &le; limits.{{supported limits/maxMultiDrawIndirectCount}}.
7443+
- |drawCountBuffer| is `null`, unless the {{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
7444+
- |drawCountBuffer| is [$valid to use with$] |this|.
7445+
- |drawCountBuffer|.{{GPUBuffer/[[usage]]}} contains {{GPUBufferUsage/INDIRECT}}.
7446+
- |drawCountOffset| + sizeof([=indirect multiDrawIndexed count=]) &le;
7447+
|drawCountBuffer|.{{GPUBuffer/[[size]]}}.
7448+
- |drawCountOffset| is a multiple of 4.
7449+
</div>
7450+
1. Add |indirectBuffer| and |drawCountBuffer| (if given) to the [=usage scope=] as [=internal usage/input=].
7451+
</div>
7452+
</div>
7453+
</dl>
73547454

73557455
<div algorithm>
73567456
To determine if it's <dfn abstract-op>valid to draw</dfn> with {{GPURenderEncoderBase}} |encoder|
@@ -9292,26 +9392,20 @@ The following enums are supported if and only if the {{GPUFeatureName/"depth32fl
92929392

92939393
## <dfn dfn-type=enum-value dfn-for=GPUFeatureName>multi-draw-indirect</dfn> ## {#multi-draw-indirect}
92949394

9295-
Allows {{GPURenderEncoderBase/drawIndirect()}} and {{GPURenderEncoderBase/drawIndexedIndirect()}} to
9296-
operate on arrays of [=indirect draw parameters=] and [=indirect drawIndexed parameters=] respectively
9297-
and allows `firstInstance` to be greater than 0.
9395+
Allows the use of the {{GPURenderEncoderBase/multiDrawIndirect()}} and
9396+
{{GPURenderEncoderBase/multiDrawIndexedIndirect()}} methods and removes the zero value restriction on
9397+
`firstInstance` in [=indirect draw parameters=] and [=indirect drawIndexed parameters=].
92989398

9299-
**Feature Function Arguments**
9399+
**Feature Methods**
93009400

9301-
The following optional function arguments are supported if and only if the
9302-
{{GPUFeatureName/"multi-draw-indirect"}} [=feature=] is enabled.
9401+
The following methods are supported if and only if the {{GPUFeatureName/"multi-draw-indirect"}}
9402+
[=feature=] is enabled.
93039403

93049404
<dl>
9305-
: {{GPURenderEncoderBase/drawIndirect()}}
9306-
::
9307-
* <l>{{GPURenderEncoderBase/drawIndirect(indirectBuffer, indirectOffset)/maxDrawCount}}</l>
9308-
* <l>{{GPURenderEncoderBase/drawIndirect(indirectBuffer, indirectOffset)/drawCountBuffer}}</l>
9309-
* <l>{{GPURenderEncoderBase/drawIndirect(indirectBuffer, indirectOffset)/drawCountOffset}}</l>
9310-
: {{GPURenderEncoderBase/drawIndexedIndirect()}}
9405+
: {{GPURenderEncoderBase}}
93119406
::
9312-
* <l>{{GPURenderEncoderBase/drawIndexedIndirect(indirectBuffer, indirectOffset)/maxDrawCount}}</l>
9313-
* <l>{{GPURenderEncoderBase/drawIndexedIndirect(indirectBuffer, indirectOffset)/drawCountBuffer}}</l>
9314-
* <l>{{GPURenderEncoderBase/drawIndexedIndirect(indirectBuffer, indirectOffset)/drawCountOffset}}</l>
9407+
* {{GPURenderEncoderBase/multiDrawIndirect()}}
9408+
* {{GPURenderEncoderBase/multiDrawIndexedIndirect()}}
93159409
</dl>
93169410

93179411

0 commit comments

Comments
 (0)