Skip to content

Broken GPU Instancing - Performance Degradation Upgrading From MRTK2 Standard Shader #234

@Schroedingers-Cat

Description

@Schroedingers-Cat

Upgrading From MRTK2's Standard Shader Breaks GPU Instancing And Causes Performance Degradation

After upgrading our project to MRTK3, we observed our app's framerate dropping down to 30-40 fps in a scene with 520 instances of 4 variants of low-vertex-count models, sharing the same opaque material with GPU Instancing enabled. We identified the source of the issue being the new GraphicsTools/Standard (GTS) shader from MRTK3 Graphics Tools. Switching back to MixedRealityToolkit/Standard (MRTS) shader eliminated the issue and brought us back up to 60 FPS.

We investigated this with RenderDoc and the difference between the two seems to be that GTS is ignoring its Material's GPU Instancing setting causing a much higher event count per frame than when using MRTS. RenderDoc.zip

With the MRTS shader, instanced objects are drawn with very few DrawIndexedInstanced(IndexCountPerInstance, InstanceCount) calls, often with the InstanceCount argument being tens or hundreds: Image
But with the GTS shader, DrawIndexedInstanced always gets called with only 1 as InstanceCount argument: Image

To reproduce

Steps to reproduce the behavior:

  1. Download, extract and open this project MRTK3 Shader Performance Degradation.zip
  2. Open the scene MRTK3 Shader Performance Issue.unity which has meshes all using the same material HäuserColourMap
  3. Verify that this material uses the Graphics Tools/Standard shader (from this repository) and "GPU Instancing" is enabled
  4. Run the scene and verify that the Stats window shows Saved by batching: 0
  5. Use RenderDoc to verify that DrawIndexedInstanced is called with an instance argument of 1 leading to a high amount of render events
  6. Stop play mode
  7. Deploy a UWP build to HL2 and verify it runs at 30-40 fps
  8. On the HäuserColourMap, switch its shader to Mixed Reality Toolkit/Standard (from the MRTK2)
  9. Run the scene and verify that the Stats window shows Saved by batching ~1500
  10. Use RenderDoc to verify that DrawIndexedInstanced is called with an instance argument of tens or hundreds, leading to only a few render events
  11. Deploy a UWP build to HL2 and verify it runs at 60fps

Expected behavior

We expected the new default shader to not break GPU instancing (if enabled in its material settings) and to not degrade performance.

Setup

  • Unity Version 2022.3.59f1
  • Graphics Tools Version v0.8.1

Target platform

  • HoloLens 2

Additional context

It's worth noting that inspecting the new MeshInstancer example scenes with RenderDoc seems like the InstanceCount argument of the DrawIndexedInstanced call is considerably higher than one there. However, this used to work automatically with the MRTK2 shader which allowed our designers to just place content using Unity's tools.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions