Performance issue: too much uniform updates

Hi,

I’ve found an issue with the uniforms. It seams that they are sent to the GPU even if the value hasn’t changed.
In my game I was able to reduce the uniforms from ~10.000 to ~2000 which results in up to 15% of performance increase. For me it was about 10 fps more than before.

I’ve already created a pull-request which you can find here

screenshots:
http://alrik-online.de/alrik/screens/javaw%202015-06-29%2023-36-17-01.png
http://alrik-online.de/alrik/screens/javaw%202015-06-29%2023-35-09-33.png

regards,

Alrik

2 Likes

Note: it sounds like you have a LOT of materials. I wonder if you could even get better performance improvement by reorganizing your scene.

We’ve talked about doing something like this before with a way to mark some uniforms to still be updated every time (it’s very convenient for global settings, for example). I haven’t looked at your pull request so I don’t know if it lines up with what we’d discussed before.

Anyway, if reducing uniform sends gives you that much improvement then better sharing materials would likely give way way more improvements.

There are a total of 171 Material instances in my scene. Do you really think this is a lot? The GUI (chat, Hud, inventory, …) was also loaded before I made the screenshots.

Seems like a lot. What do you use for your GUI layer? For example, BitmapText should all be sharing the same material for the same font.

It just seems odd that it’s such a significant affect in your application. When I tried something similar way back it was barely noticeable.

The most of them are from t0neg0dGUI as you can see here:

...
38 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
39 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
40 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
41 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
42 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
43 MatDefs/Light/LightingArray.j3md [Boolean UseColorCorrection, Boolean SeparateTexCoord, Vector3 LightPos, Boolean LowQuality, Float Brightness : 1.0, Boolean LATC, Boolean VertexLighting, TextureArray DiffuseMap, Texture2D SpecularMap, Texture2D GlowMap, Vector4 ClippingPuffel, Float ShadowIntensity, Float WindStrength, Boolean UsePuffelClipping : false, Boolean HighQuality, Vector4 Color, Boolean EnvMapAsSphereMap, Boolean SteepParallax, Float Contrast : 1.0, Boolean UseWeavingGrass, Matrix4 LightViewProjectionMatrix1, Float AlphaDiscardThreshold, Matrix4 LightViewProjectionMatrix2, Vector3 FresnelParams, TextureArray ParallaxMap, Matrix4 LightViewProjectionMatrix0, Boolean HardwareShadows, Matrix4 LightViewProjectionMatrix5, Matrix4 LightViewProjectionMatrix3, Matrix4 LightViewProjectionMatrix4, Matrix4Array BoneMatrices, Int NumberOfBones, Texture2D ShadowMap5, Texture2D ShadowMap4, Vector4 Splits, TextureCubeMap EnvMap, Texture2D ShadowMap1, Texture2D ShadowMap0, Texture2D ShadowMap3, Texture2D ShadowMap2, Vector2 FadeInfo, Boolean UseMaterialColors, Float PCFEdge, Float ParallaxHeight : 0.05, Boolean UseFog, TextureArray NormalMap, Boolean PackedNormalParallax, Boolean UseVertexColor, Vector2 WindDirection, Vector4 Specular, Vector4 Diffuse, Float Saturation : 1.0, Boolean UseAlpha, Int FilterMode, Vector3 FogColor, Texture2D AlphaMap, Float Shininess : 1.0, Boolean WardIso, Float ShadowMapSize, Boolean StaticLighting, Vector4 Ambient, Vector4 GlowColor, Float FogDensity : 0.01, Texture2D ColorRamp, Boolean VTangent, Boolean Minnaert, Texture2D LightMap, Vector3 SunLightColor]
44 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
45 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
46 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
47 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
48 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
49 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
50 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
51 tonegod/gui/shaders/Unshaded.j3md [Boolean UseEffectTexCoords : false, Boolean UseClipping : false, Boolean EffectImageSwap : false, Float TextRangeStart : 0.0, Float LastUpdate, Texture2D ColorMap, Boolean IsTextField : false, Float EffectStep, Texture2D EffectMap, Float GlobalAlpha : 1.0, Boolean HasTabFocus : false, Vector4 EffectColor, Boolean UseEffect : false, Boolean EffectFade : false, Float CaretSpeed : 10.0, Boolean EffectPulseColor : false, Vector2 OffsetTexCoord, Vector4 Color, Float TextRangeEnd : 0.0, Texture2D AlphaMap, Boolean VertexColor, Boolean EffectPulse : false, Float CaretX : 1.0, Vector4 Clipping, Boolean EffectSaturate : false, Vector2 OffsetAlphaTexCoord, Boolean ShowTextRange : false]
...

I have tested my version of Uniorm.java in the test case “TestSceneStress”. The uniforms counter goes from ~60.000 down to ~30.000. But you are right, there is no significant performance improvement. So you think only the huge amount of materials causes the performance increase with my version of Uniform.java? Hm that sounds really odd :-/

But how can I reduce the amount of materials? All materials has different parameter value. And what about models loaded from j3o files? Every model has its own texture and so on.

And note: I’m not saying your change is bad. We’ve talked about it a few times. (It will need a way to still get continuous updates like now for Object-based values like Vector3f, ColorRGBA, etc. because right now those are auto-updated and many materials in the wild rely on that.)

I’m not sure where your performance issue comes from but you also do have a lot of objects in your scene. I don’t know what your scene construction looks like and/or how many of your 1000 objects-in-view are UI or what.

Regarding UI stuff, yeah, even Lemur would create a ton of materials for a UI with lots of elements… even when they share component configuration. (Though it could be fixed, I guess.) It’s the nature of a UI… but it also shouldn’t cause that much performance issues on a decent card.

hm strange. I have a AMD ATI 290x graphics card, so I shouldn’t be worried.
Until now I hadn’t the case where the material parameters are modified without calling setVector3, setVector4, … So this isn’t a problem for me. In my changes, I modified the way how the values are copied. Before that, the object references like Vector4f were directly copied into the uniform variable. Now I create a new Object for the first use and only set the value for the next time and if it is different than before. Therefore no object reference will be copied in the future. On the basis of this, I’m able to compare the new incoming value with the old value. If incoming value isn’t different than the old one: prevent reuploading to the GPU otherwise set “updateNeeded” to true.

Concerning UI stuff: I have no idea how to reuse/share materials with different parameters such as color, clipping coords and so on.

Many of us use the current feature as a sort of ‘custom local globals’ thing. For example, you can set something like fogColor = someColorRGBA on a bunch of materials and then you only have to change someColorRGBA to affect the fog color of all of those materials (say for day/night cycling).

Anyway, from comments I understand your patch is invalid because it’s mostly formatting changes. If that can be fixed then we might apply it if we have time to keep backwards compatibility (or you could add that and default it to auto-update unless the user specifies otherwise for these types of parameters).

Yeah, you can’t really. Though most UI components tend to have the same values… at least in the typical GUI.

Ok I try to modify my changes to allow the old and the new way. Is it a good/bad idea to extent setValue(VarType type, Object value) by an optional boolean parameter to control the desired way?

Edit: hm I think it should be possible to the user to control the desired way when creating the material or am I wrong?

Not sure how. It seems to me that it would be uniform/material parameter specific. Like setting a flag on that uniform or something.