@@ -580,6 +580,7 @@ void WebGPUGraph::execute() {
580580namespace {
581581
582582struct MapCallbackData {
583+ bool done = false ;
583584 WGPUMapAsyncStatus status = WGPUMapAsyncStatus_Error;
584585};
585586
@@ -590,6 +591,7 @@ void buffer_map_callback(
590591 void * /* userdata2*/ ) {
591592 auto * data = static_cast <MapCallbackData*>(userdata1);
592593 data->status = status;
594+ data->done = true ;
593595}
594596
595597} // namespace
@@ -598,29 +600,35 @@ void WebGPUGraph::copy_outputs(std::vector<std::pair<void*, size_t>>& outputs) {
598600 const size_t count = std::min (outputs.size (), output_staging_buffers_.size ());
599601
600602 std::vector<MapCallbackData> cb_data (count);
601- std::vector<WGPUFuture> map_futures (count, WGPUFuture{});
602603
603604 for (size_t i = 0 ; i < count; i++) {
604605 if (outputs[i].second == 0 ) {
606+ cb_data[i].done = true ;
605607 cb_data[i].status = WGPUMapAsyncStatus_Success;
606608 continue ;
607609 }
608610 WGPUBufferMapCallbackInfo cb_info = {};
609- cb_info.mode = WGPUCallbackMode_WaitAnyOnly ;
611+ cb_info.mode = WGPUCallbackMode_AllowSpontaneous ;
610612 cb_info.callback = buffer_map_callback;
611613 cb_info.userdata1 = &cb_data[i];
612- map_futures[i] = wgpuBufferMapAsync (
614+ wgpuBufferMapAsync (
613615 output_staging_buffers_[i],
614616 WGPUMapMode_Read,
615617 0 ,
616618 outputs[i].second ,
617619 cb_info);
618620 }
619621
620- for (size_t i = 0 ; i < count; i++) {
621- if (outputs[i].second != 0 &&
622- webgpu_wait (instance_, map_futures[i]) != WGPUWaitStatus_Success) {
623- throw std::runtime_error (" WebGPU: WaitAny failed for output map" );
622+ // WaitAny returns pre-queue on CI Dawn+SwiftShader here; pump until mapped.
623+ bool all_mapped = false ;
624+ while (!all_mapped) {
625+ webgpu_poll (instance_);
626+ all_mapped = true ;
627+ for (size_t i = 0 ; i < count; i++) {
628+ if (outputs[i].second != 0 && !cb_data[i].done ) {
629+ all_mapped = false ;
630+ break ;
631+ }
624632 }
625633 }
626634
0 commit comments