By default WebGPU only allows wgpu::BufferUsage::MapWrite to be combined with wgpu::BufferUsage::CopySrc. Uploading data that the GPU consumes as a uniform, vertex, index, storage or indirect buffer therefore requires a separate staging buffer and an explicit copy on every update.
The wgpu::FeatureName::BufferMapWriteExtendedUsages feature removes this restriction: it allows creating a buffer with wgpu::BufferUsage::MapWrite combined with any other wgpu::BufferUsage, except wgpu::BufferUsage::MapRead. This makes it possible to write directly into a mappable buffer that is also GPU-usable, eliminating the staging buffer and the extra copy.
The feature works on the GPUs with either cache-coherent or non-cache-coherent Unified Memory Architecture (UMA), where we can effectively upload data from CPU to GPU through mapped pointer, and directly access the data on GPU without any extra copies.
This is a subset of the more permissive BufferMapExtendedUsages feature, which additionally allows wgpu::BufferUsage::MapRead to be combined with arbitrary usages but is only available on a narrower set of hardware (cache-coherent UMA). Because it is a superset, enabling BufferMapExtendedUsages on a device implicitly enables BufferMapWriteExtendedUsages as well.
The table below summarizes the requirement to enable this feature on D3D12, Metal and Vulkan:
| Backend | Requirement to enable | Backing memory for write-only mapping |
|---|---|---|
| Direct3D 12 | D3D12_FEATURE_DATA_ARCHITECTURE.UMA == TRUE | Custom heap (D3D12_HEAP_TYPE_CUSTOM) in the L0 system memory pool (D3D12_MEMORY_POOL_L0), with CPU page property D3D12_CPU_PAGE_PROPERTY_WRITE_BACK on cache-coherent UMA or D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE on non-cache-coherent UMA. |
| Metal | [MTLDevice hasUnifiedMemory] == YES | MTLResourceStorageModeShared allocation with MTLResourceCPUCacheModeWriteCombined; no didModifyRange: / synchronization needed. |
| Vulkan | A memory type exposing VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT. | A HOST_COHERENT (write-combined) memory type; VK_MEMORY_PROPERTY_HOST_CACHED_BIT is not required, so non-cache-coherent UMA GPUs are supported. |
New feature name wgpu::FeatureName::BufferMapWriteExtendedUsages. It is currently experimental (see crbug.com/386255678).
Once enabled, wgpu::BufferUsage::MapWrite can be combined with any other wgpu::BufferUsage except wgpu::BufferUsage::MapRead.
wgpu::BufferDescriptor descriptor; descriptor.size = size; // MapWrite can now be combined with any usage other than MapRead. descriptor.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::Uniform; wgpu::Buffer uniformBuffer = device.CreateBuffer(&descriptor); uniformBuffer.MapAsync(wgpu::MapMode::Write, 0, size, wgpu::CallbackMode::AllowSpontaneous, [uniformBuffer, size](wgpu::MapAsyncStatus status, wgpu::StringView) { if (status == wgpu::MapAsyncStatus::Success) { memcpy(uniformBuffer.GetMappedRange(), data, size); uniformBuffer.Unmap(); } });
wgpu::BufferUsage::MapWrite with non-wgpu::BufferUsage::CopySrc usages.wgpu::BufferUsage::MapRead cannot be combined with other GPU usages under this feature.memcpy out of the mapped range) may be extremely slow because the underlying memory is typically uncached on CPU.