gecko-dev/gfx/wr/webrender/doc/swizzling.md

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

32 строки
3.3 KiB
Markdown
Исходник Обычный вид История

Bug 1548339 - WR swizzle configuration of texture units r=gw Allow the swizzle to be configurable with a texture binding. This is still experimental and needs to be tested well on all platforms. Basic approach is the following: - WR device figures out how it can use BGRA and makes the texture cache format configurable at run-time. It tries to make the uploads to the shared texture cache pages to be done without any driver conversions, and without extra memory allocated. - it also reports the preferred input format for the images, which may be different from the texture cache format - if WR texture cache is asked to allocate a shared texture with a different (swizzled) format from the preferred, it associates the cache entry with a swizzle - the swizzle becomes a part of the `SourceTexture`, which affects batch splitting - when a texture reaches binding by GL device, it checks whether the current swizzle on this texture doesn't match the given one, and configures the texture sampling accordingly - we can't use blits with swizzling, so when that needs to happen we use `cs_copy` path, which is now mostly rewritten The idea is that Gecko would ask WR for the preferred format and configure its image decoding to produce image data that doesn't require any swizzling. The PR changes existing texture upload (and batching) paths. On Linux, if texture storage is available, we now use it and provide the data as RGBA, assuming no conversion by the driver. The swizzling kicks in when we sample this data in the shader. On Windows/Angle we use BGRA as an internal format for texture cache and expect Gecko to provide BGRA data, this should be unchanged. Differential Revision: https://phabricator.services.mozilla.com/D21965 --HG-- extra : moz-landing-system : lando
2019-07-26 17:55:50 +03:00
> It'd be great to have some (in-tree) docs describing the process you've worked through here, the overall motivation, how it works on different GPUs / platforms etc. Perhaps as a follow up?
# Swizzling in WR
## Problem statement
The goal is to avoid the CPU conversion of data done by the driver on texture data uploads. It's slow and always done synchronously, hurting our "Renderer" thread CPU utilization.
Gecko produces all of the image data in BGRA. Switching "imagelib" to RGBA is possible, but modifying Skia to follow is less trivial.
OpenGL support for BGRA8 as an internal texture format is a complex story: it's officially supported in Angle and a fair share of Android devices, but it's not available on the desktop GL (and until recently wasn't available in the Android emulator). Unofficially, when textures are initialized with `glTexImage` (as opposed to `glTexStorage`) with RGBA internal format, the desktop GL drivers often prefer to store the data in BGRA8 format, actually.
The only way to avoid the CPU conversion is to provide the data in exactly the same format that the driver is using internally for a texture. In this case, the driver does a straght `memcpy` into its CPU-visible memory, which is the best we can hope for with OpenGL API.
## Solution: swizzling
https://phabricator.services.mozilla.com/D21965 is providing the solution to this problem. The main principles are:
1. Use `glTexStorage` whenever it's available. Doing so gives us full control of the internal format, also allows to avoid allocating memory for mipmaps that we don't use.
2. Make the shared texture cache format to be determined at the init time, based on the GL device capabilities. For Angle and OpenGL ES this is BGRA8, for desktop this is RGBA8 (since desktop GL doesn't support BGRA internal formats). WebRender is now able to tell Gecko, which color format it prefers the texture data to use.
3. If the data comes in a format that is different from our best case, we pretend that the data is actually in our best case format, and associate the allocated cache entry with the `Swizzle`. That swizzle configuration changes the way shaders sample from a texture, adjusting for the fact the data was provided in a different format.
4. The lifetime of a "swizzled" texture cache data is starting at the point the data is uploaded and ending at a point where any shader samples from this data. Any other operation on that data (copying or blitting) is not configurable by `Swizzle` and thus would produce incorrect results. To address this, the change enhances `cs_copy` shader to be used in place of blitting from the texture cache, where needed.
5. Swizzling becomes a part of the batch key per texture. Mixing up draw calls with texture data that is differently swizzled then introduces the batch breaks. This is a downside for the swizzling approach in general, but it's not clear to what extent this would affect Gecko.
## Code paths
Windows/Angle and Android:
- we use `glTexStorage` with BGRA8 internal format, no swizzling is needed in general case.
Windows (non-Angle), Mac, Linux:
- if `glTexStorage` is available, we use it with RGBA8 internal format, swizzling everything on texture sampling.
- otherwise, we use RGBA unsized format with `gTexImage` and expect the data to come in BGRA format, no swizzling is involved.