Page MenuHomeWildfire Games

[rc] GL_ARB instancing to reduce draw calls
Needs ReviewPublic

Authored by wraitii on Aug 5 2020, 5:53 PM.

Details

Reviewers
vladislavbelov
Summary

On GitHub: https://github.com/wraitii/0ad/tree/instancing

This uses GL_ARB_draw_instanced to render some models using instancing instead of individual draw calls.
Batch size is calculated by hwdetect.js, and can be reset via the "max_matrix_uniform" config value.
Cuts draw calls anywhere between 50 and 75% on a typical frame (F11 to check).

Other approaches would be to use vertex attributes with divisor (good support), or uniform buffer objects or just buffer textures, but those have much lower support (according to https://feedback.wildfiregames.com/results/ )

ISSUES:

  • Limited instancing of animated models (most unit meshes...). This could be fixed with more extensions. For now, I think it instances trireme oars OK since those are animated in perfect sync.

TODO:

  • Separate the renderer-only changes from the instancing changes.

Good stuff to test:

  • Gaul barracks.
  • Sahydian buttes or whatever it's called.
  • Combat demo huge (with gpuskinning=true)

Personal profiling shows a 10-20% perf difference, depending on the map.

Test Plan

Compile this, run it using preferGLSL, compare FPS with not using preferGLSL, check out how many draw calls are saved (F11)

You can test instancing via:

Engine.ConfigDB_CreateValue("user", "max_matrix_uniform", "1");
Engine.ConfigDB_CreateValue("user", "max_matrix_uniform", "64"); (NB -> your real max value might be higher/lower)

Event Timeline

wraitii created this revision.Aug 5 2020, 5:53 PM
Owners added a subscriber: Restricted Owners Package.Aug 5 2020, 5:53 PM
Vulcan added a comment.Aug 5 2020, 5:58 PM

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/vs2015-differential/2356/display/redirect

Vulcan added a comment.Aug 5 2020, 6:00 PM

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2898/display/redirect

wraitii requested review of this revision.Aug 5 2020, 6:12 PM
asterix added a subscriber: asterix.Aug 5 2020, 8:57 PM

Thank you so much for your hard work.

wraitii updated this revision to Diff 13129.Aug 7 2020, 10:43 AM

Updated version with less terrible code, and also enables using "preferglsl=no" so you can compare with a baseline.
On my intel card, the GLSL version with instancing is always faster, while also being better looking.

I've added a way to see how many draw calls are saved via F11. This is actually cutting draw calls anywhere between 50% to 75% on a typical frame, and sometimes much more (siyad buttes,...)
I'm actually quite impressed at how efficient this is.
(I'm using 64-batches here, but 32 doesn't change much).

I'll ugprade this from POC to WIP I think - the renderer changes are imo rather positive in general, and since support for GL_ARB_draw_instanced is basically 100% according to statistics I think we should enable it by default.

As vladislavbelov noted, we could also use GL_ARB_instanced_arrays to use VertexAttribDivisor, but:

  • I'm not certain if I can just bind arbitrary data to arbitrary vertex pointers (there are comments in the code hinting that no?)
  • it actually seems more complex to setup
  • Using 32-sized uniforms is generally good enough and we could somewhat easily fetch the max value from openGL and use a bigger value.

(still not supporting GPU skinning).

wraitii retitled this revision from [POC] GL_ARB instancing to reduce draw calls to [wip] GL_ARB instancing to reduce draw calls.Aug 7 2020, 10:45 AM
wraitii edited the summary of this revision. (Show Details)
wraitii edited the test plan for this revision. (Show Details)
wraitii added inline comments.Aug 7 2020, 10:47 AM
source/renderer/InstancingModelRenderer.cpp
360

This might actually make ARB performance slightly worse than it should be with the GetUniformBinding, need to check

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/vs2015-differential/2393/display/redirect

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2938/display/redirect

wraitii updated this revision to Diff 13130.Aug 7 2020, 12:01 PM
wraitii edited the summary of this revision. (Show Details)

Switch back to 32 to get more pessimistic improvements (better for testing imo).
Also fix the slight ARB pessimisation.

Also "fix" GPU skinning to render something, though all models will have the same animation, which looks very broken.

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2939/display/redirect

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/vs2015-differential/2394/display/redirect

wraitii updated this revision to Diff 13131.Aug 7 2020, 12:34 PM

Fix GPU skinning. In general don't expect to really benefit from instancing, but I think this might actually instance trireme oars somewhat (at least testing locally), so that might be positive.

At this point the only TODOs I can think of are:

  • fixing the pgl stuff
  • using a GL setting instead of hardcoding 32
  • cleaning up the code a tad

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2940/display/redirect

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/vs2015-differential/2395/display/redirect

wraitii updated this revision to Diff 13132.Aug 7 2020, 1:53 PM
wraitii retitled this revision from [wip] GL_ARB instancing to reduce draw calls to [rc] GL_ARB instancing to reduce draw calls.
wraitii edited the test plan for this revision. (Show Details)

Fixes a remaining issue with GPUs skinning.
Fixed the pgl stuff locally, so enabling it.

I'm using a sorta hack to make things configurable. You can test instancing via:

Engine.ConfigDB_CreateValue("user", "max_matrix_uniform", "1");
Engine.ConfigDB_CreateValue("user", "max_matrix_uniform", "64"); (NB -> your real max value might be higher/lower)

With that, only the cleanup remains if we do decide to merge it I think.

wraitii edited the summary of this revision. (Show Details)Aug 7 2020, 2:03 PM
Vulcan added a comment.Aug 7 2020, 2:26 PM

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Source...

source/renderer/Renderer.cpp
[ 173] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 179] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 185] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 191] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 197] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 203] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 209] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 215] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 221] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 227] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 233] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 239] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.
Executing section JS...
**** ESLintBear (spaced-comment) [Section <empty> | Severity NORMAL] ****
!    ! Expected space or tab after '//' in comment.
[----] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[++++] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[ 349] 	//print(JSON.stringify(settings, null, 1)+"\n");
[ 349] 	// print(JSON.stringify(settings, null, 1)+"\n");
**** ESLintBear (spaced-comment) [Section <empty> | Severity NORMAL] ****
!    ! Expected space or tab after '//' in comment.
[----] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[++++] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[ 353] 	//print(JSON.stringify(output, null, 1)+"\n");
[ 353] 	// print(JSON.stringify(output, null, 1)+"\n");

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 179] »   var·disable_audio·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_audio' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 180] »   var·disable_s3tc·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_s3tc' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 181] »   var·disable_shadows·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadows' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 182] »   var·disable_shadowpcf·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadowpcf' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 183] »   var·disable_allwater·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_allwater' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 184] »   var·disable_fancywater·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_fancywater' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 185] »   var·enable_glsl·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_glsl' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 186] »   var·enable_postproc·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_postproc' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 187] »   var·enable_smoothlos·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_smoothlos' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 188] »   var·override_renderpath·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'override_renderpath' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 224] »   //·Enable·GLSL·on·OpenGL ES 2.0+,·which·doesn’t·support·the·fixed
**** ESLintBear (no-irregular-whitespace) [Section: JS | Severity: NORMAL] ****
!    ! Irregular whitespace not allowed.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 224] »   //·Enable·GLSL·on·OpenGL ES 2.0+,·which·doesn’t·support·the·fixed
**** ESLintBear (no-irregular-whitespace) [Section: JS | Severity: NORMAL] ****
!    ! Irregular whitespace not allowed.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 179] »   var·disable_audio·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_audio' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 180] »   var·disable_s3tc·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_s3tc' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 181] »   var·disable_shadows·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadows' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 182] »   var·disable_shadowpcf·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadowpcf' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 183] »   var·disable_allwater·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_allwater' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 184] »   var·disable_fancywater·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_fancywater' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 185] »   var·enable_glsl·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_glsl' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 186] »   var·enable_postproc·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_postproc' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 187] »   var·enable_smoothlos·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_smoothlos' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 188] »   var·override_renderpath·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'override_renderpath' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 224] »   //·Enable·GLSL·on·OpenGL ES 2.0+,·which·doesn’t·support·the·fixed
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! This line contains non-breaking spaces: http://jshint.com/docs/options/#nonbsp
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2941/display/redirect

I made some quick profiling. I noticed that the amount of draw calls is halfed. I also tested value 1 against 64. 64 is much faster. But compared to the non patched replay, there was a performance hit by ~10-20%.
Does this hit come from your new profiler option "saved draw calls"? I think some calculations of profiler are active, even if you don't have open the profiler panel. Do you have a non profiler version to test?

I also got this compiler warnings
\source\renderer/ModelVertexRenderer.h(158): warning C4100: "model": Unreferenzierter formaler Parameter (Quelldatei wird kompiliert ..\..\..\source\renderer\InstancingModelRenderer.cpp)
\source\renderer/ModelVertexRenderer.h(158): warning C4100: "shader": Unreferenzierter formaler Parameter (Quelldatei wird kompiliert ..\..\..\source\renderer\InstancingModelRenderer.cpp)
\source\renderer/ModelVertexRenderer.h(158): warning C4100: "model": Unreferenzierter formaler Parameter (Quelldatei wird kompiliert ..\..\..\source\renderer\HWLightingModelRenderer.cpp)
\source\renderer/ModelVertexRenderer.h(158): warning C4100: "shader": Unreferenzierter formaler Parameter (Quelldatei wird kompiliert ..\..\..\source\renderer\HWLightingModelRenderer.cpp)
\source\renderer/ModelVertexRenderer.h(158): warning C4100: "model": Unreferenzierter formaler Parameter (Quelldatei wird kompiliert ..\..\..\source\renderer\ModelRenderer.cpp)
\source\renderer/ModelVertexRenderer.h(158): warning C4100: "shader": Unreferenzierter formaler Parameter (Quelldatei wird kompiliert ..\..\..\source\renderer\ModelRenderer.cpp)

wraitii added a comment.EditedAug 7 2020, 3:04 PM

I made some quick profiling. I noticed that the amount of draw calls is halfed. I also tested value 1 against 64. 64 is much faster. But compared to the non patched replay, there was a performance hit by ~10-20%.

It should be a straight improvement on svn, so this seems odd. How did you replay exactly? Were you using GPU skinning? Were you using prefer glsl? What map?

Edit -> Also what is your graphics card?

It should be a straight improvement on svn, so this seems odd. How did you replay exactly? Were you using GPU skinning? Were you using prefer glsl? What map?

I always use a 200 units replay on sahydian buttes, camera will not moved or zoomed. What is GPU skinning? GSLS enabled.

Edit -> Also what is your graphics card?

Radeon RX 5700

wraitii added a comment.EditedAug 7 2020, 3:20 PM

I always use a 200 units replay on sahydian buttes, camera will not moved or zoomed. What is GPU skinning? GSLS enabled.

gpuskinning is an option in default.cfg that you have to activate using the config file. You could try (de)/activating that

What are you reporting as being 10/20% slower exactly?

Edit: I feel like your GC might be too good. Can you try capping max_matrix_uniform to maybe 64 in hwdetect.js ?

OptimusShepard added a comment.EditedAug 7 2020, 3:53 PM

gpuskinning is an option in default.cfg that you have to activate using the config file. You could try (de)/activating that

Setting it disabled doesn't change anything.

What are you reporting as being 10/20% slower exactly?

The whole frame.

Edit: I feel like your GC might be too good. Can you try capping max_matrix_uniform to maybe 64 in hwdetect.js ?

That's it. Thx


Render: red non patch, green patched.

wraitii edited the summary of this revision. (Show Details)Aug 7 2020, 4:39 PM
wraitii updated this revision to Diff 13138.Aug 7 2020, 4:40 PM

Cap the instancing uniform at 64 following Optimus' testing.

This might mean that it'd be good to use a vertex attribue with vertexAttribDivisor instead, as vladislav suggested.

Vulcan added a comment.Aug 7 2020, 5:12 PM

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Source...

source/renderer/Renderer.cpp
[ 173] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 179] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 185] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 191] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 197] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 203] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 209] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 215] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 221] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 227] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 233] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.

source/renderer/Renderer.cpp
[ 239] »   »   return·buf;
**** CPPCheckBear (returnDanglingLifetime) [Section: Source | Severity: MAJOR] ****
!    ! Returning pointer to local variable 'buf' that will be invalid when returning.
Executing section JS...
**** ESLintBear (spaced-comment) [Section <empty> | Severity NORMAL] ****
!    ! Expected space or tab after '//' in comment.
[----] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[++++] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[ 349] 	//print(JSON.stringify(settings, null, 1)+"\n");
[ 349] 	// print(JSON.stringify(settings, null, 1)+"\n");
**** ESLintBear (spaced-comment) [Section <empty> | Severity NORMAL] ****
!    ! Expected space or tab after '//' in comment.
[----] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[++++] /zpool0/trunk/binaries/data/mods/mod/hwdetect/hwdetect.js
[ 353] 	//print(JSON.stringify(output, null, 1)+"\n");
[ 353] 	// print(JSON.stringify(output, null, 1)+"\n");

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 179] »   var·disable_audio·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_audio' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 180] »   var·disable_s3tc·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_s3tc' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 181] »   var·disable_shadows·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadows' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 182] »   var·disable_shadowpcf·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadowpcf' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 183] »   var·disable_allwater·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_allwater' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 184] »   var·disable_fancywater·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_fancywater' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 185] »   var·enable_glsl·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_glsl' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 186] »   var·enable_postproc·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_postproc' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 187] »   var·enable_smoothlos·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_smoothlos' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 188] »   var·override_renderpath·=·undefined;
**** ESLintBear (no-undef-init) [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'override_renderpath' to undefined.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 224] »   //·Enable·GLSL·on·OpenGL ES 2.0+,·which·doesn’t·support·the·fixed
**** ESLintBear (no-irregular-whitespace) [Section: JS | Severity: NORMAL] ****
!    ! Irregular whitespace not allowed.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 224] »   //·Enable·GLSL·on·OpenGL ES 2.0+,·which·doesn’t·support·the·fixed
**** ESLintBear (no-irregular-whitespace) [Section: JS | Severity: NORMAL] ****
!    ! Irregular whitespace not allowed.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 179] »   var·disable_audio·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_audio' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 180] »   var·disable_s3tc·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_s3tc' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 181] »   var·disable_shadows·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadows' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 182] »   var·disable_shadowpcf·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_shadowpcf' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 183] »   var·disable_allwater·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_allwater' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 184] »   var·disable_fancywater·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'disable_fancywater' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 185] »   var·enable_glsl·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_glsl' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 186] »   var·enable_postproc·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_postproc' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 187] »   var·enable_smoothlos·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'enable_smoothlos' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 188] »   var·override_renderpath·=·undefined;
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! It's not necessary to initialize 'override_renderpath' to 'undefined'.

binaries/data/mods/mod/hwdetect/hwdetect.js
[ 224] »   //·Enable·GLSL·on·OpenGL ES 2.0+,·which·doesn’t·support·the·fixed
**** JSHintBear [Section: JS | Severity: NORMAL] ****
!    ! This line contains non-breaking spaces: http://jshint.com/docs/options/#nonbsp
Executing section cli...

Link to build: https://jenkins.wildfiregames.com/job/docker-differential/2946/display/redirect

myou5e added a subscriber: myou5e.Aug 22 2020, 12:33 AM

This might mean that it'd be good to use a vertex attribue with vertexAttribDivisor instead, as vladislav suggested.

I'd like to see comparison. Also glVertexAttribDivisor actually allows you to use a single vertex buffer during all draw calls. Which means that you need bind/setup/update it only once before drawing.

Stan added a subscriber: Stan.Nov 11 2020, 3:01 AM

Needs a rebase (CStrInternStatic) I see no perf increase with my 1070, so maybe it's only for lower end cards.

I'd like @vladislavbelov to look at it though since it can save up to 10 000 drawcalls per frame and more in atlas.

source/renderer/InstancingModelRenderer.cpp
404