Skip to content

Implement GPUBuffer.mapAsync and update wgpu-core#27084

Merged
bors-servo merged 5 commits intoservo:masterfrom
kunalmohan:gpu-buffer-mapping
Jun 27, 2020
Merged

Implement GPUBuffer.mapAsync and update wgpu-core#27084
bors-servo merged 5 commits intoservo:masterfrom
kunalmohan:gpu-buffer-mapping

Conversation

@kunalmohan
Copy link
Copy Markdown
Contributor

@kunalmohan kunalmohan commented Jun 25, 2020

This PR covers the following-

  1. update wgpu-core to use serializable RenderPass and ComputePass. Implement DispatchIndirect.
  2. Implement GPUBuffer.mapAsync().

The mapAsync() methods has the following flow-

  1. A new promise is created in mapAsync() and a message sent to the server-side. This returns a promise.
  2. On the server-side, a struct BufferMapInfo object stores the relevant info required to send data to the client-side on completion of mapping. This object is stored in a buffer_maps: HashMap<id::BufferId, BufferMapInfo<'a>>, in WGPU. buffers_maps basically stores the data for buffers with pending mapping.
  3. buffer_map_async() command is issued with a callback responsible to send the data back to the client.
  4. All the devices are polled every time the server receives a new message.
  5. The data is sent back on completion and promise resolved through AsyncWGPUListener (similar to how the requestDevice() and RequestAdapter are processed).
  6. On receiving the data, the client sends back a BufferMapComplete message to the server to remove the entry from buffer_maps hashmap.

I intended to implement getMappedRange(), too, in this PR but it's quite a task in itself (implementing intersecting ArrayBuffers). This already being a 500+ line PR, I thought it best to get this model approved first (also it will probably be easier to review this and getMappedRange separately). getMappedRange would come up in the next one.


  • ./mach build -d does not report any errors
  • ./mach test-tidy does not report any errors
  • These changes fix #___ (GitHub issue number if applicable)
  • There are tests for these changes OR
  • These changes do not require tests because ___

@highfive
Copy link
Copy Markdown

Heads up! This PR modifies the following files:

  • @asajeffrey: components/script/dom/webidls/GPUComputePassEncoder.webidl, components/script/dom/gpucomputepassencoder.rs, components/script/dom/gpumapmode.rs, components/script/dom/gpubuffer.rs, components/script/dom/webidls/GPUBuffer.webidl and 10 more
  • @KiChjang: components/script/dom/webidls/GPUComputePassEncoder.webidl, components/script/dom/gpucomputepassencoder.rs, components/script/dom/gpumapmode.rs, components/script/dom/gpubuffer.rs, components/script/dom/webidls/GPUBuffer.webidl and 10 more

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Jun 25, 2020
@highfive
Copy link
Copy Markdown

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!
  • These commits modify script code, but no tests are modified. Please consider adding a test!

@kunalmohan
Copy link
Copy Markdown
Contributor Author

r?@kvark

@highfive highfive assigned kvark and unassigned asajeffrey Jun 25, 2020
@kvark
Copy link
Copy Markdown
Member

kvark commented Jun 25, 2020

All the devices are polled every time the server receives a new message.

That's technically fine, but a bit scary nonetheless. In Gecko, we are polling the devices every 100ms, which is supposed to be configurable in the future, see code. Might be worth doing something like this in Servo.

Copy link
Copy Markdown
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! Just a few notes here

@kunalmohan
Copy link
Copy Markdown
Contributor Author

kunalmohan commented Jun 26, 2020

I have addressed most of the review comments. I am still unsure about the last one- about how that would be done. I'll try to dig into it but maybe it will be better to solve that along with get_mapped_range() depending how the data will be exposed to the user. I can convert this to a draft and continue implementing get_mapped_range() here itself if that's a better idea.

(This line count of PR increased just because of new TAB space for the full block of code inside run() in webgpu/lib.rs)

Copy link
Copy Markdown
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a chat about this on "#wgpu:matrix.org", and it looks like the PR is on the right track:)

@kunalmohan
Copy link
Copy Markdown
Contributor Author

@kvark I have changed the Unmapping process to use get_mapped_range() to write back the data to buffer while unmapping in case of mapAsync as well as mapped_at_creation.

Copy link
Copy Markdown
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable, thank you!

@kvark
Copy link
Copy Markdown
Member

kvark commented Jun 27, 2020

@bors-servo r+

@bors-servo
Copy link
Copy Markdown
Contributor

📌 Commit 183a43d has been approved by kvark

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Jun 27, 2020
@kunalmohan
Copy link
Copy Markdown
Contributor Author

error[E0599]: no method named `handle_mut` found for struct `dom::bindings::trace::RootedTraceableBox<mozjs_sys::jsgc::Heap<*mut js::jsapi::JSObject>>` in the current scope
    --> components/script/dom/gpubuffer.rs:284:62
     |
284  |                         MutableHandle::from_raw(self.mapping.handle_mut()),
     |                                                              ^^^^^^^^^^ method not found in `dom::bindings::trace::RootedTraceableBox<mozjs_sys::jsgc::Heap<*mut js::jsapi::JSObject>>`
     | 
    ::: components/script/dom/bindings/trace.rs:1036:1
     |
1036 | pub struct RootedTraceableBox<T: 'static + JSTraceable> {
     | ------------------------------------------------------- method `handle_mut` not found for this
error[E0599]: no method named `handle_mut` found for struct `dom::bindings::trace::RootedTraceableBox<mozjs_sys::jsgc::Heap<_>>` in the current scope
    --> components/script/dom/gpudevice.rs:189:53
     |
189  |                     MutableHandle::from_raw(mapping.handle_mut()),
     |                                                     ^^^^^^^^^^ method not found in `dom::bindings::trace::RootedTraceableBox<mozjs_sys::jsgc::Heap<_>>`
     | 
    ::: components/script/dom/bindings/trace.rs:1036:1
     |
1036 | pub struct RootedTraceableBox<T: 'static + JSTraceable> {
     | ------------------------------------------------------- method `handle_mut` not found for this

checks failed. I didn't get this on my system earlier, but on a rebase against master I can see it failing now. I'll rectify this and push the changes.

@kunalmohan kunalmohan force-pushed the gpu-buffer-mapping branch from 183a43d to 434466f Compare June 27, 2020 15:52
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Jun 27, 2020
@kunalmohan kunalmohan force-pushed the gpu-buffer-mapping branch from 434466f to db2d313 Compare June 27, 2020 16:02
@kvark
Copy link
Copy Markdown
Member

kvark commented Jun 27, 2020

@bors-servo r+

@bors-servo
Copy link
Copy Markdown
Contributor

📌 Commit db2d313 has been approved by kvark

@highfive highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Jun 27, 2020
@highfive highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Jun 27, 2020
@bors-servo
Copy link
Copy Markdown
Contributor

⌛ Testing commit db2d313 with merge 1ea332e...

bors-servo added a commit that referenced this pull request Jun 27, 2020
Implement GPUBuffer.mapAsync and update wgpu-core

<!-- Please describe your changes on the following line: -->
This PR covers the following-
1. update wgpu-core to use serializable `RenderPass` and `ComputePass`. Implement `DispatchIndirect`.
2. Implement `GPUBuffer.mapAsync()`.

The `mapAsync()` methods has the following flow-
1. A new promise is created in `mapAsync()` and a message sent to the server-side. This returns a promise.
2. On the server-side, a `struct BufferMapInfo` object stores the relevant info required to send data to the client-side on completion of mapping. This object is stored in a `buffer_maps: HashMap<id::BufferId, BufferMapInfo<'a>>,` in `WGPU`. `buffers_maps` basically stores the data for buffers with pending mapping.
3. `buffer_map_async()` command is issued with a callback responsible to send the data back to the client.
4. All the devices are polled every time the server receives a new message.
5. The data is sent back on completion and promise resolved through `AsyncWGPUListener` (similar to how the `requestDevice()` and `RequestAdapter` are processed).
6. On receiving the data, the client sends back a `BufferMapComplete` message to the server to remove the entry from `buffer_maps` hashmap.

I intended to implement `getMappedRange()`, too, in this PR but it's quite a task in itself (implementing intersecting ArrayBuffers). This already being a 500+ line PR, I thought it best to get this model approved first (also it will probably be easier to review this and `getMappedRange` separately). `getMappedRange` would come up in the next one.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #___ (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
@bors-servo
Copy link
Copy Markdown
Contributor

💔 Test failed - status-taskcluster

@highfive highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Jun 27, 2020
@jdm
Copy link
Copy Markdown
Member

jdm commented Jun 27, 2020

@bors-servo
Copy link
Copy Markdown
Contributor

⌛ Testing commit db2d313 with merge af110ac...

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-tests-failed The changes caused existing tests to fail. labels Jun 27, 2020
@bors-servo
Copy link
Copy Markdown
Contributor

☀️ Test successful - status-taskcluster
Approved by: kvark
Pushing af110ac to master...

@bors-servo bors-servo merged commit af110ac into servo:master Jun 27, 2020
@highfive highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Jun 27, 2020
@kunalmohan kunalmohan deleted the gpu-buffer-mapping branch June 27, 2020 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants