← 输入框|github.com|刷新
Skip to content

Promise versions of create*Pipeline - #184

Merged
kainino0x merged 1 commit into
gpuweb:masterfrom
kainino0x:pipeline-promise
Feb 1, 2019
Merged

kainino0x merged 1 commit into
gpuweb:masterfrom
kainino0x:pipeline-promise

Conversation

@kainino0x

@kainino0x kainino0x commented Jan 25, 2019 •

Copy link
Copy Markdown
Contributor
  • Promise<GPUComputePipeline> createReadyComputePipeline(...);
  • Promise<GPURenderPipeline> createReadyRenderPipeline(...);

Fixes #128.

* Promise<GPUComputePipeline> createReadyComputePipeline(...);
* Promise<GPURenderPipeline> createReadyRenderPipeline(...);
@kainino0x

kainino0x commented Jan 25, 2019 •

Copy link
Copy Markdown
Contributor Author

PR for discussion. Some thoughts:

I'm thinking about the timelines. In principle create*Pipeline is on the "device" timeline, I guess. What I'm thinking is the actual creation of a pipeline should not block other work; it should only block once they're used. (maybe other create*s too? maybe createBufferMapped?) This could be done by having applications do create*Pipeline on a worker, but just like with the recent KHR_parallel_shader_compile discussions in WebGL, we probably ought to do it in the implementation.

Normally it would be "As-If" pipeline creation occurs on the device timeline. However, As-If sort of breaks down now since you can know the status of the pipeline:

createReadyRenderPipeline
do some other round-trip operation (like a readback)

As-If might imply the pipeline will come back before the readback. (Depends on how strict we are with the callback ordering.) But the readback can (and should be able to) come back before the pipeline.

@litherum

Copy link
Copy Markdown
Contributor

Presumably the "ready" ones are guaranteed to be not-internally-null?

@kainino0x

Copy link
Copy Markdown
Contributor Author

I haven't decided on this yet, and it is kind of related to the tryCreateBuffer/Texture calls. (Sorry I haven't gotten that PR out yet.) If there is a validation error (i.e. an error in the descriptor), there are 2 options:

  1. Reject promise. So if the promise resolves, the pipeline is definitely internally valid.
  2. Resolve promise with an internally-invalid pipeline object.

The first one seems more obvious. The argument for the second one is that it might make sense to do this with tryCreateBuffer (resolve to internally null on validation error, reject on failure to allocate), and the two should probably match.

Another interesting case is device loss. If the device is lost while createReadyPipeline is in flight, should it reject or resolve with an internally-invalid object? (tryCreateBuffer and createReadyPipeline should presumably both do the same thing here.)

I'm leaning toward 1. above: tryCreateBuffer and createReadyPipeline ONLY reject on validation error (including device loss), and tryCreateBuffer returns Promise<GPUBuffer?>. I will think about this further and implement something in ErrorHandling.md when I open my PR, so allow me to wrap that all up and open it for discussion there.

@kainino0x

Copy link
Copy Markdown
Contributor Author

I ended up describing the behavior here:

c2113f5#diff-36cdb2543bb47498b85893f020401aadR120
because I wanted it to match as closely as possible with tryCreate*.

@kvark

kvark commented Feb 1, 2019

Copy link
Copy Markdown
Contributor

I'm still missing the description of why this is needed, could you point me to it?

Pipeline creation should be fairly deterministic from the user point of view:

  • if there is a validation error, I don't see why we should allow the user to recover from it. They should have provided proper shaders and the state already.
  • if there is some weird backend error like OutOfMemory, it shouldn't be expected for pipeline creation, and I'd vote for it to also be non-recoverable.
  • any asynchronicity will happen at the backend level (e.g. parallel shader compilation).

@kainino0x

Copy link
Copy Markdown
Contributor Author

It's just so that the app can avoid using the pipeline until it's finished compiling, so it doesn't end up with a frame that blocks on compilation.

It could be a status query, but the status queries we had (that are removed in the current version of #197) were also asynchronous, so really the same.

@kainino0x

kainino0x commented Feb 1, 2019 •

Copy link
Copy Markdown
Contributor Author

Re: validation error and weird backend error, I would be fine with turning those into "resolves to invalid object" instead of "rejects". (Would do the same change to tryCreate* in #197)

@kvark kvark left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok, makes sense now!

@kainino0x

Copy link
Copy Markdown
Contributor Author

I ended up making that change (always resolves, sometimes to invalid, instead of sometimes rejecting) in #197, but it's tentative.

I'm going to go ahead and merge this with its 2 reviews; semantics are described in #197 for symmetry with tryCreate*.

@kainino0x
kainino0x merged commit 7ca2004 into gpuweb:master Feb 1, 2019
@kainino0x
kainino0x deleted the pipeline-promise branch February 1, 2019 22:04
JusSn pushed a commit to JusSn/gpuweb that referenced this pull request Feb 10, 2019
* Promise<GPUComputePipeline> createReadyComputePipeline(...);
* Promise<GPURenderPipeline> createReadyRenderPipeline(...);
JusSn pushed a commit to JusSn/gpuweb that referenced this pull request Mar 26, 2019
* Promise<GPUComputePipeline> createReadyComputePipeline(...);
* Promise<GPURenderPipeline> createReadyRenderPipeline(...);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants