You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Impeller] Support instanced rendering in the Impeller HAL. #154145
Impeller doesn't support instanced rendering with base vertex specification today. It is not portable across all platforms and client rendering APIs Impeller supports today.
OpenGL ES 2.0 doesn't support instanced rendering at all (without extensions). Metal does support instanced rendering but not on MTLGPUFamilyMac1 and MTLGPUFamilyApple2 and earlier families per the Metal Feature Set Tables. Vulkan does seem to support instanced rendering everywhere and MoltenVK has an emulation for the older GPU families.
It should be trivial to support instanced rendering via emulation as a start and add fast paths for newer devices. These should cover the vast majority of devices.
How would we use instancing though? Wouldn't that require some sort of analysis step for the display list to determine what can be instanced, potentially eating any GPU gains with CPU cycles?
The impetus for this issue was Flutter GPU. I don't think we necessarily have a use case within the framework where we'd go out of our way to reduce draw calls. The rendering intent there is fairly discordant and doesn't result in that many calls to begin with.
Hence the lower priority right now. But it might be a fun idea to expose higher level APIs that can take advantage of instancing (for particle systems maybe).
Instancing is basic HAL functionality supported by almost all devices that run Flutter today (> iPhone 6). In the 2D renderer, stuff like glyph sampling or DrawPoints could be made faster by reducing the volume of vertex data that needs to be generated.
I'm not sure how emulating instancing would work for GLES. gl_InstanceIndex can be used to arbitrarily fetch per-instance data from uniforms, SSBOs, or even Textures. So we'd probably need to get rid of gl_InstanceIndex and lock down per-instance data to a specific managed convention so we can re-write shaders for our emulation, which I'm not sure would be a good idea.
GLES 3 supports glDrawArraysInstanced/glDrawElementsInstanced. To optionally support instancing in the GLES backend, I think we should also optionally support SSBOs (since we'd be relying on GLES 3 anyways for the feature) and prefer to use those as the backend-independent solution for looking up per-instance data. Other options for binding per-instance data are not really sufficient:
Indexing into a uniform array with gl_InstanceIndex would be bad because uniform data is of course very limited.
Binding the per-instance data as vertex attributes and using glVertexAttribDivisor isn't great either because it's an exotic GL-ism and I don't think there's a Metal equivalent (there is, however, a Vulkan extension for this with questionable device coverage):
If I compile shaders with GLSL ES 3 for SSBO support, it stops using legacy uniform semantics, so our uniform location lookup routine w/ glGetUniformLocation stops working.
[ RUN ] Play/RendererTest.CanRenderPerspectiveCube/OpenGLES
2024-10-13 23:43:58.529 impeller_unittests[6722:8385232] Metal API Validation Enabled
2024-10-13 23:43:58.529 impeller_unittests[6722:8385232] Metal GPU Validation Enabled
../../flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc:132: Failure
Impeller Validation Error
Could not query the location of an active uniform.
../../flutter/impeller/renderer/backend/gles/pipeline_library_gles.cc:239: Failure
Impeller Validation Error
Could not build pipeline vertex descriptors.
../../flutter/impeller/renderer/renderer_unittests.cc:189: Failure
Value of: pipeline
Actual: false
Expected: true
W.r.t. Flutter GPU shader compilation for SSBOs and instancing: We can probably have impellerc detect when an SSBO is present and mark the shader as "SSBO supporting" & automatically set a modern GLES version, and then throw a Dart exception if the SSBO cap check fails while loading the shader library (which in this case would be for all GLES, until we can add optional support).
Activity
gaaclarke commentedon Sep 26, 2024
How would we use instancing though? Wouldn't that require some sort of analysis step for the display list to determine what can be instanced, potentially eating any GPU gains with CPU cycles?
chinmaygarde commentedon Sep 26, 2024
The impetus for this issue was Flutter GPU. I don't think we necessarily have a use case within the framework where we'd go out of our way to reduce draw calls. The rendering intent there is fairly discordant and doesn't result in that many calls to begin with.
Hence the lower priority right now. But it might be a fun idea to expose higher level APIs that can take advantage of instancing (for particle systems maybe).
bdero commentedon Sep 26, 2024
Instancing is basic HAL functionality supported by almost all devices that run Flutter today (> iPhone 6). In the 2D renderer, stuff like glyph sampling or DrawPoints could be made faster by reducing the volume of vertex data that needs to be generated.
bdero commentedon Oct 14, 2024
I'm not sure how emulating instancing would work for GLES.
gl_InstanceIndexcan be used to arbitrarily fetch per-instance data from uniforms, SSBOs, or even Textures. So we'd probably need to get rid ofgl_InstanceIndexand lock down per-instance data to a specific managed convention so we can re-write shaders for our emulation, which I'm not sure would be a good idea.GLES 3 supports
glDrawArraysInstanced/glDrawElementsInstanced. To optionally support instancing in the GLES backend, I think we should also optionally support SSBOs (since we'd be relying on GLES 3 anyways for the feature) and prefer to use those as the backend-independent solution for looking up per-instance data. Other options for binding per-instance data are not really sufficient:gl_InstanceIndexwould be bad because uniform data is of course very limited.glVertexAttribDivisorisn't great either because it's an exotic GL-ism and I don't think there's a Metal equivalent (there is, however, a Vulkan extension for this with questionable device coverage):bdero commentedon Oct 14, 2024
If I compile shaders with GLSL ES 3 for SSBO support, it stops using legacy uniform semantics, so our uniform location lookup routine w/
glGetUniformLocationstops working.bdero commentedon Oct 15, 2024
W.r.t. Flutter GPU shader compilation for SSBOs and instancing: We can probably have impellerc detect when an SSBO is present and mark the shader as "SSBO supporting" & automatically set a modern GLES version, and then throw a Dart exception if the SSBO cap check fails while loading the shader library (which in this case would be for all GLES, until we can add optional support).
[Impeller] Support instanced rendering across all backends (flutter#1…
[Flutter GPU] Add instanced draw support (#187359)
[Impeller] Support instanced rendering across all backends (flutter#1…
[Flutter GPU] Add instanced draw support (flutter#187359)