Open kainino0x opened 3 years ago
Something to think about while investigating this: We may be able to do something analogous for compositingAlphaMode: "premultiplied"
, which already has unportable (but secure) compositing results, like option 4,
Thanks for filing this!
Setting color mask on each pipeline has significant cost, as Ken showed previously from WebGL land
@kainino0x hinted at it in the meeting, but I think if we clear with alpha at the beginning of the pass, and force some blend modes, then we can avoid setting writeMask. (alpha blending would always keep the one in the render target)
I can't use the same shader for rendering into the canvas and non-canvas any more (since non-canvas isn't going to use RGBX).
Do you mean the same pipeline? This seems like a tiny concern.
I can't use the same shader for rendering into the canvas and non-canvas any more (since non-canvas isn't going to use RGBX).
No shader code injection needed.
We have this "preferred format" semantics precisely because we don't know what format we'll actually want users to pick. And RGBX is only making it more complicated.
It just gives the format to the application, I'm not sure how it makes it more complicated.
IMHO 3) seems like the lowest overhead solution in part because we're doing the optimization in collaboration with the app, so only some pipelines need to be modified. It is more complicated to spec and does require the app to be aware that RGBX is a thing though.
But +1 that for MVP 1) is probably enough and we have time to see for the rest.
It just gives the format to the application, I'm not sure how it makes it more complicated.
Because now the preferred format is either rgbx8unorm
/bgrx8unorm
or rgba8unorm
/bgra8unorm
depending on which one the user wants. However I don't think this really makes things more complicated because we are going to have the same problem for rgba8unorm-srgb
/bgra8unorm-srgb
.
Tentatively moving this to post-MVP. I think we are most interested in option 2 (storeOp: "present") but it doesn't have to be done right now.
More thoughts while exploring various canvas issues:
- 1. Don't do anything (just keep the
compositingAlphaMode: "opaque"
we already have, which requires an alpha-clear and can't do so inside an existing render pass).
We might be able to detect when the alpha channel is definitely 1, by construction of the most recently executed render pass (clear value + blend mode or write mask), and elide the clear.
Or we could make it explicit and put a new flag on the GPURenderPassColorAttachment that says "alphaReadOnly" and validate the pipelines used with it, very similar to depthReadOnly/stencilReadOnly.
- 2.
storeOp: "present"
which takes away access immediately at the end of the render pass, and can either clear to 1 at the end of the pass (with a quad) or clear later. Can WebGPU canvas alpha be configured? #1425 (comment)
storeOp: "present"
which ALWAYS clears to 1 at the end of the pass (regardless of platform), avoiding the extra tracking within command buffers to take away access.
Just a note: if we take away access to the texture, we also need to take it away from the "canvas's bitmap" (used when the canvas is used as an image source - in drawImage/texImage2D/toDataURL/etc).
If not, and this is implemented as a clear on all platforms, then it's fine, the current texture and the canvas's bitmap will just be alpha-cleared.
storeOp: "present"
which ALWAYS clears to 1 at the end of the pass (regardless of platform)
This would play into the detection idea above - this would be an alternate way to trigger that fast-path without limiting yourself to specific clear values and blend/mask states. (A probably unhelpful idea is: this could also be a "clearAlpha(attachmentIndex)" command in the render pass, rather than a new storeOp.)
That said, it does still have a cost on platforms that don't need alpha cleared to 1, so I don't think this is preferable.
Tabling #1871 while we get some implementation experience. Here are some options that we should try to get experience with:
Options:
compositingAlphaMode: "opaque"
we already have, which requires an alpha-clear and can't do so inside an existing render pass).storeOp: "present"
which takes away access immediately at the end of the render pass, and can either clear to 1 at the end of the pass (with a quad) or clear later. https://github.com/gpuweb/gpuweb/issues/1425#issuecomment-809830117storeOp: "present"
which ALWAYS clears to 1 at the end of the pass (regardless of platform), avoiding the extra tracking within command buffers to take away access.See: #1871, #1425