[Impeller] use SSBOs for gradients where supported (metal/vulkan)#37654
[Impeller] use SSBOs for gradients where supported (metal/vulkan)#37654auto-submit[bot] merged 17 commits intoflutter:mainfrom
Conversation
a7921a2 to
a993117
Compare
|
I have mixed feelings about how I've currently handled the lack of support for this on Android, but also zoom zoom go fast. |
|
Converting to draft, we should use SSBOs for this |
| ] | ||
| } | ||
|
|
||
| impeller_shaders("modern_entity_shaders") { |
There was a problem hiding this comment.
This almost works, except that I fail to load the fixed_fill shaders at runtime. I suspect something somewhere is hard coded but I haven't found it. If I place these shaders in the entity shaders set (and force the gles_language version to 460 everywhere) it works as expected
| if (!context_ || !context_->IsValid()) { | ||
| return; | ||
| } | ||
| #ifdef FML_OS_ANDROID |
There was a problem hiding this comment.
TBD: actual feature selection when we have vulkan support
There was a problem hiding this comment.
Consider having a define for IMPELLER_SUPPORT_SSBO that's just IMPELLER_ENABLE_METAL || IMPELLER_ENABLE_VULKAN. Or just use the more verbose one here. You'll need some runtime detection, so an update to the Context object to have some method or struct or something that says whether SSBOs are allowed.
There was a problem hiding this comment.
Oh I see some of the runtime stuff is started.
There was a problem hiding this comment.
We need to leave this as runtime support as far as I can tell, once Vulkan is on by default. Avoids literring the code base with ifdefs too
There was a problem hiding this comment.
Can we have this on on impeller::Context instead? You can ask the context for its feature set. That way, only ES will return the legacy stuff.
| /// @brief Lowest common denominator feature sets. | ||
| constexpr BackendFeatures kLegacyBackendFeatures = {.ssbo_support = false}; | ||
|
|
||
| } // namespace impeller No newline at end of file |
|
|
||
| /// @brief A struct for describing available backend features for runtime | ||
| /// selection. | ||
| struct BackendFeatures { |
There was a problem hiding this comment.
Oh, I was thinking of this being an enum with the modern stuff implying SSBO support. But this is way better.
| if (!context_ || !context_->IsValid()) { | ||
| return; | ||
| } | ||
| #ifdef FML_OS_ANDROID |
There was a problem hiding this comment.
Can we have this on on impeller::Context instead? You can ask the context for its feature set. That way, only ES will return the legacy stuff.
ci/licenses_golden/licenses_flutter
Outdated
| FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.vert | ||
| FILE: ../../../flutter/impeller/entity/shaders/gradient_fill.vert | ||
| FILE: ../../../flutter/impeller/entity/shaders/linear_gradient_fill.frag | ||
| FILE: ../../../flutter/impeller/entity/shaders/linear_gradient_fixed_fill.frag |
There was a problem hiding this comment.
lets call this ssbo_fill perhaps?
| sl_options.vertex.fixup_clipspace = true; | ||
| if (source_options.target_platform == TargetPlatform::kOpenGLES) { | ||
| sl_options.version = 100; | ||
| sl_options.version = source_options.gles_language_version > 0 |
There was a problem hiding this comment.
I wonder if we should do source language selection based on #version directives now instead of applying command line options. Omitting them was fine when we only had a single version.
There was a problem hiding this comment.
I think that sounds reasonable, but I'm not quite sure how to make make shaderc and spirvcross work together on this. I'll file a bug
There was a problem hiding this comment.
| #define ASSERT_SIZE_NEAR(a, b) ASSERT_PRED2(&::SizeNear, a, b) | ||
| #define ASSERT_ARRAY_4_NEAR(a, b) ASSERT_PRED2(&::Array4Near, a, b) | ||
| #define ASSERT_COLOR_BUFFER_NEAR(a, b) ASSERT_PRED2(&::ColorBufferNear, a, b) | ||
| #define ASSERT_COLORS_NEAR(a, b) ASSERT_PRED2(&::ColorsNear, a, b) No newline at end of file |
|
For clarity, where we support SSBOs, there is no case where we need to use the texture upload thingy right? |
Not that I can tell. |
| for (size_t i = 1; i < stops.size(); i++) { | ||
| auto value = stops[i] - stops[i - 1]; | ||
| // Smaller than kEhCloseEnough | ||
| if (value < 0.0001) { |
There was a problem hiding this comment.
Curious, why not just use the constant instead of hardcoding the value?
There was a problem hiding this comment.
context was sort of #36218
TLDR, if you have really close stops you need a smaller number
There was a problem hiding this comment.
in the future, we'll need to stop computing the gradients on the CPU for certain stop values
|
Using purely the SSBO approach on Metal and following up with the jumbo textures thing on legacy backends sounds good to me. I reviewed the rest of the patch and it looks good to me barring the comments (mostly nits) already added. lgtm after it moves out of draft status. |
|
Needs more tests still, and need to figure out why I can't find the shaders at runtime |
|
Fun times: |
| // Sanity checks for {{def.name}} | ||
| {% if last(def.members).array_elements == 0 %} | ||
| static_assert(std::is_standard_layout_v<Shader::{{def.name}}<0>>); | ||
| static_assert(sizeof(Shader::{{def.name}}<0>) == {{def.byte_length}}); |
There was a problem hiding this comment.
This assert appears to be invalid on windows hosts, which claim this always has a sizeof 4.
There was a problem hiding this comment.
Hmm, I suppose having platform specific differences here is possible. Was the shader name in the generated shaders correct though?
|
This is ready 😄 |
| // Sanity checks for {{def.name}} | ||
| {% if last(def.members).array_elements == 0 %} | ||
| static_assert(std::is_standard_layout_v<Shader::{{def.name}}<0>>); | ||
| static_assert(sizeof(Shader::{{def.name}}<0>) == {{def.byte_length}}); |
There was a problem hiding this comment.
Hmm, I suppose having platform specific differences here is possible. Was the shader name in the generated shaders correct though?
|
Yes all of the generated code worked correctly. Though TBH I didn't find a way to use the struct generated for the SSBO, since it is dynamically sized - so I ended up creating a BufferView myself. I think that is OK though |
* a76ec91 Roll Fuchsia Linux SDK from lnmSnyJi-2H07tBnV... to WdtwlLEce90PjFJ9z... (flutter/engine#37747) * 44e2f58 [Impeller] Change texture upload pipeline in Vulkan (flutter/engine#37623) * 6a3ad3c Roll Skia from 345bceacd298 to 5270b1d26b5f (4 revisions) (flutter/engine#37748) * 0127189 Do not abort if a MultiFrameCodec is unable to allocate a bitmap buffer (flutter/engine#37534) * 54232a4 Roll Skia from 5270b1d26b5f to cf967e6b1c00 (5 revisions) (flutter/engine#37751) * 30aa3cc [fuchsia][a11y] Set explicit hit regions in flatland embedder (flutter/engine#37338) * da07c33 Make NotifyIdle reject close and past deadlines. (flutter/engine#37737) * e3844cc Add third_party/dart/third_party/binaryen/src as a dependency (flutter/engine#37749) * aeb2cd9 [Impeller] use SSBOs for gradients where supported (metal/vulkan) (flutter/engine#37654) * e8aa1c1 Roll Skia from cf967e6b1c00 to f1f59de17204 (2 revisions) (flutter/engine#37756) * 4311774 [Impeller] register modern shaders on Vulkan too (flutter/engine#37757) * 8e4a718 Made FlutterTextField that outlive FlutterTextPlatformNode not crash (flutter/engine#37735) * 446a09d [macOS] Use consistent filenames for tests (flutter/engine#37755) * 7a390f9 Roll Skia from f1f59de17204 to 12f01bc5b57e (1 revision) (flutter/engine#37760)
…15672) * a76ec91 Roll Fuchsia Linux SDK from lnmSnyJi-2H07tBnV... to WdtwlLEce90PjFJ9z... (flutter/engine#37747) * 44e2f58 [Impeller] Change texture upload pipeline in Vulkan (flutter/engine#37623) * 6a3ad3c Roll Skia from 345bceacd298 to 5270b1d26b5f (4 revisions) (flutter/engine#37748) * 0127189 Do not abort if a MultiFrameCodec is unable to allocate a bitmap buffer (flutter/engine#37534) * 54232a4 Roll Skia from 5270b1d26b5f to cf967e6b1c00 (5 revisions) (flutter/engine#37751) * 30aa3cc [fuchsia][a11y] Set explicit hit regions in flatland embedder (flutter/engine#37338) * da07c33 Make NotifyIdle reject close and past deadlines. (flutter/engine#37737) * e3844cc Add third_party/dart/third_party/binaryen/src as a dependency (flutter/engine#37749) * aeb2cd9 [Impeller] use SSBOs for gradients where supported (metal/vulkan) (flutter/engine#37654) * e8aa1c1 Roll Skia from cf967e6b1c00 to f1f59de17204 (2 revisions) (flutter/engine#37756) * 4311774 [Impeller] register modern shaders on Vulkan too (flutter/engine#37757) * 8e4a718 Made FlutterTextField that outlive FlutterTextPlatformNode not crash (flutter/engine#37735) * 446a09d [macOS] Use consistent filenames for tests (flutter/engine#37755) * 7a390f9 Roll Skia from f1f59de17204 to 12f01bc5b57e (1 revision) (flutter/engine#37760)
…15672) * a76ec91 Roll Fuchsia Linux SDK from lnmSnyJi-2H07tBnV... to WdtwlLEce90PjFJ9z... (flutter/engine#37747) * 44e2f58 [Impeller] Change texture upload pipeline in Vulkan (flutter/engine#37623) * 6a3ad3c Roll Skia from 345bceacd298 to 5270b1d26b5f (4 revisions) (flutter/engine#37748) * 0127189 Do not abort if a MultiFrameCodec is unable to allocate a bitmap buffer (flutter/engine#37534) * 54232a4 Roll Skia from 5270b1d26b5f to cf967e6b1c00 (5 revisions) (flutter/engine#37751) * 30aa3cc [fuchsia][a11y] Set explicit hit regions in flatland embedder (flutter/engine#37338) * da07c33 Make NotifyIdle reject close and past deadlines. (flutter/engine#37737) * e3844cc Add third_party/dart/third_party/binaryen/src as a dependency (flutter/engine#37749) * aeb2cd9 [Impeller] use SSBOs for gradients where supported (metal/vulkan) (flutter/engine#37654) * e8aa1c1 Roll Skia from cf967e6b1c00 to f1f59de17204 (2 revisions) (flutter/engine#37756) * 4311774 [Impeller] register modern shaders on Vulkan too (flutter/engine#37757) * 8e4a718 Made FlutterTextField that outlive FlutterTextPlatformNode not crash (flutter/engine#37735) * 446a09d [macOS] Use consistent filenames for tests (flutter/engine#37755) * 7a390f9 Roll Skia from f1f59de17204 to 12f01bc5b57e (1 revision) (flutter/engine#37760)
Use SSBO to pass the gradient color buffer to the shader, which dramatically improves performance for small gradients. When creating this color buffer, reusing the existing color buffer if the stops are even.
Fixes flutter/flutter#115208 (for iOS).
Fixes flutter/flutter#115523
On Android, any usage of arrays in the fragment shaders leads to a link error with no other messages. Assuming that we're using the gles fragment shaders, I'm not really sure what the issue is exactly - but I assume this has something to do with targeting gles 2.0.