@@ -1759,7 +1759,8 @@ def callback(status_, user_data_p):
1759
1759
self ._internal , map_mode , offset , size , callback , ffi .NULL
1760
1760
)
1761
1761
1762
- # Let it do some cycles
1762
+ # Wait for the queue to process all tasks (including the mapping of the buffer).
1763
+ # Also see WebGPU's onSubmittedWorkDone() and C's WGPUQueueWorkDoneCallback.
1763
1764
self ._device ._poll ()
1764
1765
1765
1766
if status != 0 : # no-cover
@@ -1863,6 +1864,31 @@ def write_mapped(self, data, buffer_offset=None, size=None):
1863
1864
# Copy data
1864
1865
src_m [:] = data
1865
1866
1867
+ def _experimental_get_mapped_range (self , buffer_offset = None , size = None ):
1868
+ """Undocumented and experimental. This API can change or be
1869
+ removed without notice. Just here so we can benchmark this
1870
+ approach. Returns a mapped memoryview object that can be written
1871
+ to. Note that once the buffer unmaps, this memoryview object
1872
+ becomes unusable, and accessing it may result in a segfault.
1873
+ """
1874
+ # Can we even write?
1875
+ if self ._map_state != enums .BufferMapState .mapped :
1876
+ raise RuntimeError ("Can only write to a buffer if its mapped." )
1877
+
1878
+ offset , size = self ._check_range (buffer_offset , size )
1879
+ if offset < self ._mapped_status [0 ] or (offset + size ) > self ._mapped_status [1 ]:
1880
+ raise ValueError (
1881
+ "The range for buffer writing is not contained in the currently mapped range."
1882
+ )
1883
+
1884
+ # Get mapped memoryview
1885
+ # H: void * f(WGPUBuffer buffer, size_t offset, size_t size)
1886
+ src_ptr = libf .wgpuBufferGetMappedRange (self ._internal , offset , size )
1887
+ src_address = int (ffi .cast ("intptr_t" , src_ptr ))
1888
+ src_m = get_memoryview_from_address (src_address , size )
1889
+
1890
+ return src_m
1891
+
1866
1892
def destroy (self ):
1867
1893
# NOTE: destroy means that the wgpu-core object gets into a destroyed
1868
1894
# state. The wgpu-core object still exists. So destroying is quite
0 commit comments