-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Dynamically compile shaders with uniforms instead of attributes for DDS #9185
Conversation
76909c5
to
1db4642
Compare
47c249c
to
3c2ab62
Compare
|
3c2ab62
to
761a2b0
Compare
Implementation notes:
|
761a2b0
to
ca5115b
Compare
Bench results (iPhone 6) before:
After:
|
Here are my benchmarks on the iPad mini 2:
Looking at the shaders, it looks like there are still attributes generated for some of the shaders even though they're |
ca5115b
to
8a341aa
Compare
Results are pretty much unchanged:
|
Remaining task is to convert the size attributes for symbol programs to this format as well. |
8a341aa
to
d1b1b1a
Compare
Capturing from chat: Porting symbol size to dynamic shaders is difficult. It doesn't fit in the existing
I profiled the changes here and found #9257. With that included, FPS is maxed at 60 on my iPhone. |
In 141e995, we changed the way how most values are passed to the shader from uniforms to attributes. We did this, because for DDS, we need the ability to specify a different value for every feature, e.g. to have data-driven color values. Previously, once draw call used a uniform (constant) to give all features in a draw call the same color. In 141e995, we moved to constant vertex attributes, which allows us to optionally specify vertex attribute buffers for every possible combination of DDS values. Most of the time though, these attributes are set to constants.
Constant vertex attributes are an edge case features, and the OpenGL wiki has this to say about them:
Unfortunately, using constant vertex attributes causes a performance regression on some devices. To verify that this is the case, I created an isolated benchmark to find out what the culprit is. It consisted of ~36,000 vertices. The color shader received 6 colors as input and combined them to one color with
mix
. I varied the way the colors are piped through to the fragment shader in the following three combinations:uniform vec4 u_colorN
directly in the fragment shader: 36 fpsuniform vec4 u_colorN
in the vertex shader, with avarying vec4 v_colorN
to pass the colors from the vertex to the fragment shader: 30fpsattribute vec4 a_colorN
in the vertex shader, with avarying vec4 v_colorN
to pass the colors from the vertex to the fragment shader, with constant vertex attributes: 26 fpsThese results make it look like this performance regression is a combination of two issues (at least on the iPad mini 2):
It's worth noting, that we had a very similar issue on WebGL in IE: mapbox/mapbox-gl-js#1714. In JS, we're now using a different implementation that generates shader code at run-time, and uses uniforms when the DDS attribute is constant.
Therefore, I believe we'll have to switch our DDS code to a similar model that JS uses where we dynamically generate shader code at runtime based on whether the stylesheet uses data-driven values for a certain property.
I think the way we could support this is by adding
#defines
into the shader code that recompiling the shader with certain defines based on whether an attribute uses a data-driven value or not.#defines
in the generated shader code to selectively toggle between attribute and uniformDataDrivenPaintProperty
-derived classes/cc @jfirebaugh