@@ -2882,7 +2882,9 @@ enum GPUFeatureName {
28822882 "clip-distances",
28832883 "dual-source-blending",
28842884 "subgroups",
2885- "buffer-map-extended-usages",
2885+ "buffer-map-write-with-extended-usages",
2886+ "buffer-map-write-with-extended-usages-and-gpu-data",
2887+ "buffer-map-read-with-extended-usages",
28862888};
28872889</script>
28882890
@@ -3041,17 +3043,6 @@ to.
30413043 <!-- As needed, compute more allowed usages based on the features enabled on the device. -->
30423044</div>
30433045
3044- <div algorithm data-timeline=const>
3045- A {{GPUDevice}}'s <dfn dfn>GPU-writable buffer usages</dfn> are:
3046-
3047- - Always allowed:
3048- {{GPUBufferUsage/COPY_DST}},
3049- {{GPUBufferUsage/STORAGE}},
3050- {{GPUBufferUsage/QUERY_RESOLVE}}
3051-
3052- <!-- As needed, compute more allowed usages based on the features enabled on the device. -->
3053- </div>
3054-
30553046## Example ## {#initialization-examples}
30563047
30573048<div class=example>
@@ -3363,16 +3354,21 @@ The {{GPUBufferUsage}} flags determine how a {{GPUBuffer}} may be used after its
33633354 The buffer can be mapped for reading. (Example: calling {{GPUBuffer/mapAsync()}} with
33643355 {{GPUMapMode/READ|GPUMapMode.READ}})
33653356
3366- May only be combined with {{GPUBufferUsage/COPY_DST }} when
3367- {{GPUFeatureName/buffer-map-extended-usages}} is not enabled .
3357+ Unless {{GPUFeatureName/buffer-map-read-with-extended-usages }} is enabled, this may only be
3358+ combined with {{GPUBufferUsage/COPY_DST}} .
33683359
33693360 : <dfn>MAP_WRITE</dfn>
33703361 ::
33713362 The buffer can be mapped for writing. (Example: calling {{GPUBuffer/mapAsync()}} with
33723363 {{GPUMapMode/WRITE|GPUMapMode.WRITE}})
33733364
3374- May only be combined with {{GPUBufferUsage/COPY_SRC}} when
3375- {{GPUFeatureName/buffer-map-extended-usages}} is not enabled.
3365+ Unless {{GPUFeatureName/buffer-map-write-with-extended-usages}} is enabled, this may only be
3366+ combined with {{GPUBufferUsage/COPY_SRC}}.
3367+
3368+ When {{GPUFeatureName/buffer-map-write-with-extended-usages}} is enabled:
3369+ - This cannot be combined with {{GPUBufferUsage/INDEX}} or {{GPUBufferUsage/INDIRECT}}.
3370+ - This cannot be combined with {{GPUBufferUsage/MAP_READ}} unless
3371+ {{GPUFeatureName/buffer-map-read-with-extended-usages}} is enabled.
33763372
33773373 : <dfn>COPY_SRC</dfn>
33783374 ::
@@ -3467,17 +3463,31 @@ The {{GPUBufferUsage}} flags determine how a {{GPUBuffer}} may be used after its
34673463 - |descriptor|.{{GPUBufferDescriptor/usage}} must not be 0.
34683464 - |descriptor|.{{GPUBufferDescriptor/usage}} must be a subset of the
34693465 [=allowed buffer usages=] for |this|.
3470- - If {{GPUFeatureName/buffer-map-extended-usages}} is not enabled on |this|:
3471- - If |descriptor|.{{GPUBufferDescriptor/usage}} contains {{GPUBufferUsage/MAP_READ}}:
3472- - |descriptor|.{{GPUBufferDescriptor/usage}} must contain no other flags
3473- except {{GPUBufferUsage/COPY_DST}}.
3474- - If |descriptor|.{{GPUBufferDescriptor/usage}} contains {{GPUBufferUsage/MAP_WRITE}}:
3475- - |descriptor|.{{GPUBufferDescriptor/usage}} must contain no other flags
3476- except {{GPUBufferUsage/COPY_SRC}}.
3466+ - If |descriptor|.{{GPUBufferDescriptor/usage}} contains
3467+ {{GPUBufferUsage/MAP_WRITE}}:
3468+ - If {{GPUFeatureName/buffer-map-write-with-extended-usages}} is not
3469+ enabled on |this|:
3470+ - |descriptor|.{{GPUBufferDescriptor/usage}} must contain no other
3471+ flags except {{GPUBufferUsage/COPY_SRC}}.
3472+ - Else:
3473+ - |descriptor|.{{GPUBufferDescriptor/usage}} must not contain
3474+ {{GPUBufferUsage/INDEX}} or {{GPUBufferUsage/INDIRECT}}.
3475+ - If |descriptor|.{{GPUBufferDescriptor/usage}} contains
3476+ {{GPUBufferUsage/MAP_READ}}:
3477+ - If {{GPUFeatureName/buffer-map-read-with-extended-usages}} is not
3478+ enabled on |this|:
3479+ - |descriptor|.{{GPUBufferDescriptor/usage}} must contain no other
3480+ flags except {{GPUBufferUsage/COPY_DST}}.
34773481 - If |descriptor|.{{GPUBufferDescriptor/size}} must be ≤
34783482 |this|.{{GPUObjectBase/[[device]]}}.{{device/[[limits]]}}.{{supported limits/maxBufferSize}}.
34793483 </div>
34803484
3485+ Note: {{GPUBufferUsage/MAP_WRITE}} is not allowed to work with
3486+ {{GPUBufferUsage/INDEX}} or {{GPUBufferUsage/INDIRECT}} because the data in the
3487+ buffers with {{GPUBufferUsage/INDEX}} or {{GPUBufferUsage/INDIRECT}} usage may be
3488+ validated on the GPU, and allowing updating such buffer on the CPU side may cause
3489+ potential TOCTOU attacks in a compromised JavaScript process.
3490+
34813491 Note: If buffer creation fails, and |descriptor|.{{GPUBufferDescriptor/mappedAtCreation}} is `false`,
34823492 any calls to {{GPUBuffer/mapAsync()}} will reject, so any resources allocated to enable mapping can
34833493 and may be discarded or recycled.
@@ -3597,42 +3607,32 @@ The {{GPUMapMode}} flags determine how a {{GPUBuffer}} is mapped when calling
35973607<dl dfn-type=const dfn-for=GPUMapMode>
35983608 : <dfn>READ</dfn>
35993609 ::
3600- Only valid with buffers created with the {{GPUBufferUsage/MAP_READ}} usage.
3610+ Only valid with {{GPUBuffer}}s created with the {{GPUBufferUsage/MAP_READ}} usage.
36013611
3602- Once the buffer is mapped, calls to {{GPUBuffer/getMappedRange()}} will return an
3603- {{ArrayBuffer}} containing the buffer 's current values.
3612+ Once the {{GPUBuffer}} is mapped, calls to {{GPUBuffer/getMappedRange()}} will return an
3613+ {{ArrayBuffer}} containing the {{GPUBuffer}} 's current values.
36043614
36053615 Changes to the returned {{ArrayBuffer}} will be discarded after {{GPUBuffer/unmap()}} is
36063616 called.
36073617
36083618 : <dfn>WRITE</dfn>
36093619 ::
3610- Only valid with buffers created with the {{GPUBufferUsage/MAP_WRITE}} usage.
3611-
3612- When the buffer is created without [=GPU-writable buffer usages=]:
3613- Once the buffer is mapped, calls to {{GPUBuffer/getMappedRange()}} will return an
3614- {{ArrayBuffer}} containing the buffer’s current values.
3620+ Only valid with {{GPUBuffer}}s created with the {{GPUBufferUsage/MAP_WRITE}} usage.
36153621
3616- When the buffer is created with [=GPU-writable buffer usages=]:
3617- Once the buffer is mapped, calls to {{GPUBuffer/getMappedRange()}} will return an
3618- {{ArrayBuffer}} containing the default initialized data (zeros) or data written by the
3619- webpage during a previous mapping.
3622+ Once the buffer is mapped:
3623+ - If {{GPUFeatureName/buffer-map-write-with-extended-usages-and-GPU-data}} is enabled:
3624+ - Calls to {{GPUBuffer/getMappedRange()}} will return an {{ArrayBuffer}} containing the
3625+ {{GPUBuffer}}'s current values.
3626+ - Else:
3627+ - Calls to {{GPUBuffer/getMappedRange()}} will return an {{ArrayBuffer}} containing
3628+ the default initialized data (zeros) or data written by the webpage during a
3629+ previous mapping.
36203630
3621- Changes to the returned {{ArrayBuffer}} will be stored in the buffer after
3631+ Changes to the returned {{ArrayBuffer}} will be stored in the {{GPUBuffer}} after
36223632 {{GPUBuffer/unmap()}} is called.
36233633
3624- Note: Write-only mapping will never return values produced by the GPU.
3625-
3626- : <dfn>READ|WRITE</dfn>
3627- ::
3628- Only valid with buffers created with the {{GPUBufferUsage/MAP_READ}} and
3629- {{GPUBufferUsage/MAP_WRITE}} usage.
3630-
3631- Once the buffer is mapped, calls to {{GPUBuffer/getMappedRange()}} will return an
3632- {{ArrayBuffer}} containing the buffer's current values.
3633-
3634- Changes to the returned {{ArrayBuffer}} will be stored in the buffer after
3635- {{GPUBuffer/unmap()}} is called.
3634+ Note: Write-only mapping will never return values produced by the GPU unless
3635+ {{GPUFeatureName/buffer-map-write-with-extended-usages-and-GPU-data}} is enabled.
36363636
36373637</dl>
36383638
@@ -3717,8 +3717,7 @@ The {{GPUMapMode}} flags determine how a {{GPUBuffer}} is mapped when calling
37173717 - |rangeSize| is a multiple of 4.
37183718 - |offset| + |rangeSize| ≤ |this|.{{GPUBuffer/size}}
37193719 - |mode| contains only bits defined in {{GPUMapMode}}.
3720- - If {{GPUFeatureName/buffer-map-extended-usages}} is not enabled on |this|.device:
3721- - |mode| contains exactly one of {{GPUMapMode/READ}} or {{GPUMapMode/WRITE}}.
3720+ - |mode| contains exactly one of {{GPUMapMode/READ}} or {{GPUMapMode/WRITE}}.
37223721 - If |mode| contains {{GPUMapMode/READ}} then |this|.{{GPUBuffer/usage}} must contain {{GPUBufferUsage/MAP_READ}}.
37233722 - If |mode| contains {{GPUMapMode/WRITE}} then |this|.{{GPUBuffer/usage}} must contain {{GPUBufferUsage/MAP_WRITE}}.
37243723 </div>
@@ -16756,20 +16755,45 @@ expose real values whenever the feature is available on the adapter:
1675616755- New WGSL extensions:
1675716756 - [=extension/subgroups=]
1675816757
16759- <h3 id=dom-gpufeaturename-buffer-map-extended-usages data-dfn-type=enum-value data-dfn-for=GPUFeatureName>`"buffer-map-extended-usages"`
16758+ <h3 id=dom-gpufeaturename-buffer-map-write-with-extended-usages data-dfn-type=enum-value data-dfn-for=GPUFeatureName>`"buffer-map-write-with-extended-usages"`
16759+ </h3>
16760+
16761+ Allows the creation of {{GPUBuffer}}s with {{GPUBufferUsage/MAP_WRITE}} combined with more
16762+ {{GPUBufferUsage}} flags besides {{GPUBufferUsage/COPY_SRC}} on the GPUs that support uploading data
16763+ to GPU without a staging buffer.
16764+
16765+ This feature adds the following [=optional API surfaces=]:
16766+ - Allows the use of {{GPUBufferUsage/MAP_WRITE}} with any other {{GPUBufferUsage}}s listed below as
16767+ |descriptor|.{{GPUBufferDescriptor/usage}} in the creation of {{GPUBuffer}}s:
16768+ - {{GPUBufferUsage/COPY_DST}}
16769+ - {{GPUBufferUsage/VERTEX}}
16770+ - {{GPUBufferUsage/UNIFORM}}
16771+ - {{GPUBufferUsage/STORAGE}}
16772+ - {{GPUBufferUsage/QUERY_RESOLVE}}
16773+
16774+ <h3 id=dom-gpufeaturename-buffer-map-write-with-extended-usages-and-GPU-data data-dfn-type=enum-value data-dfn-for=GPUFeatureName>`"buffer-map-write-with-extended-usages-and-GPU-data"`
1676016775</h3>
1676116776
16762- Allows the creation of mappable {{GPUBuffer}}s with any other {{GPUBufferUsage}} flags, and allows
16763- setting both {{GPUMapMode/READ}} and {{GPUMapMode/WRITE}} bits as a valid map mode in
16764- {{GPUBuffer}}.{{GPUBuffer/mapAsync()}}.
16777+ Allows the creation of {{GPUBuffer}}s with {{GPUBufferUsage/MAP_WRITE}} combined with more
16778+ {{GPUBufferUsage}} flags besides {{GPUBufferUsage/COPY_SRC}}, and directly reading the data on the
16779+ GPU with {{GPUBuffer/getMappedRange()}} on the GPUs that support uploading data to GPU without a
16780+ staging buffer and take advantage of CPU-cached memory.
16781+
16782+ This feature adds the following [=optional API surfaces=]:
16783+ - Enable {{GPUFeatureName/buffer-map-write-with-extended-usages}}
16784+ - Calls to {{GPUBuffer/getMappedRange()}} will return an {{ArrayBuffer}} containing the
16785+ {{GPUBuffer}}'s current values.
16786+
16787+ <h3 id=dom-gpufeaturename-buffer-map-read-with-extended-usages data-dfn-type=enum-value data-dfn-for=GPUFeatureName>`"buffer-map-read-with-extended-usages"`
16788+ </h3>
16789+
16790+ Allows the creation of {{GPUBuffer}}s with {{GPUBufferUsage/MAP_READ}} combined with
16791+ {{GPUBufferUsage}} flags besides {{GPUBufferUsage/COPY_DST}} on the GPUs that take advantage of
16792+ CPU-cached memory.
1676516793
1676616794This feature adds the following [=optional API surfaces=]:
1676716795- Allows the use of {{GPUBufferUsage/MAP_READ}} with any other {{GPUBufferUsage}} flags as
1676816796 |descriptor|.{{GPUBufferDescriptor/usage}} in the creation of {{GPUBuffer}}s.
16769- - Allows the use of {{GPUBufferUsage/MAP_WRITE}} with any other {{GPUBufferUsage}} flags as
16770- |descriptor|.{{GPUBufferDescriptor/usage}} in the creation of {{GPUBuffer}}s.
16771- - Allows setting both {{GPUMapMode/READ}} and {{GPUMapMode/WRITE}} bits in the `mode` parameter of
16772- {{GPUBuffer}}.{{GPUBuffer/mapAsync()}}.
1677316797
1677416798# Appendices # {#appendices}
1677516799
0 commit comments