-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Impeller] use SSBOs for gradients where supported (metal/vulkan) #37654
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 |
@@ -66,6 +66,20 @@ impeller_shaders("entity_shaders") { | |||
] | |||
} | |||
|
|||
impeller_shaders("modern_entity_shaders") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -150,13 +150,26 @@ ContentContext::ContentContext(std::shared_ptr<Context> context) | |||
if (!context_ || !context_->IsValid()) { | |||
return; | |||
} | |||
#ifdef FML_OS_ANDROID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBD: actual feature selection when we have vulkan support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see some of the runtime stuff is started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/// @brief Lowest common denominator feature sets. | ||
constexpr BackendFeatures kLegacyBackendFeatures = {.ssbo_support = false}; | ||
|
||
} // namespace impeller |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newline at EOF.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
/// @brief A struct for describing available backend features for runtime | ||
/// selection. | ||
struct BackendFeatures { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I was thinking of this being an enum with the modern stuff implying SSBO support. But this is way better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -150,13 +150,26 @@ ContentContext::ContentContext(std::shared_ptr<Context> context) | |||
if (!context_ || !context_->IsValid()) { | |||
return; | |||
} | |||
#ifdef FML_OS_ANDROID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -1285,6 +1286,7 @@ FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.frag | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets call this ssbo_fill perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -45,10 +45,14 @@ static CompilerBackend CreateGLSLCompiler(const spirv_cross::ParsedIR& ir, | |||
sl_options.force_zero_initialized_variables = true; | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -141,3 +158,4 @@ inline ::testing::AssertionResult ColorBufferNear( | |||
#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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Newline at EOF.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious, why not just use the constant instead of hardcoding the value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
context was sort of #36218
TLDR, if you have really close stops you need a smaller number
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
|
@@ -202,7 +202,6 @@ using Shader = {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader; | |||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assert appears to be invalid on windows hosts, which claim this always has a sizeof 4.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I suppose having platform specific differences here is possible. Was the shader name in the generated shaders correct though?
This is ready 😄 |
@@ -202,7 +202,6 @@ using Shader = {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader; | |||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
…115672) * a76ec9158 Roll Fuchsia Linux SDK from lnmSnyJi-2H07tBnV... to WdtwlLEce90PjFJ9z... (flutter/engine#37747) * 44e2f5854 [Impeller] Change texture upload pipeline in Vulkan (flutter/engine#37623) * 6a3ad3c14 Roll Skia from 345bceacd298 to 5270b1d26b5f (4 revisions) (flutter/engine#37748) * 01271891c Do not abort if a MultiFrameCodec is unable to allocate a bitmap buffer (flutter/engine#37534) * 54232a4c3 Roll Skia from 5270b1d26b5f to cf967e6b1c00 (5 revisions) (flutter/engine#37751) * 30aa3cc38 [fuchsia][a11y] Set explicit hit regions in flatland embedder (flutter/engine#37338) * da07c33d2 Make NotifyIdle reject close and past deadlines. (flutter/engine#37737) * e3844cc1e Add third_party/dart/third_party/binaryen/src as a dependency (flutter/engine#37749) * aeb2cd95b [Impeller] use SSBOs for gradients where supported (metal/vulkan) (flutter/engine#37654) * e8aa1c192 Roll Skia from cf967e6b1c00 to f1f59de17204 (2 revisions) (flutter/engine#37756) * 4311774fb [Impeller] register modern shaders on Vulkan too (flutter/engine#37757) * 8e4a718d0 Made FlutterTextField that outlive FlutterTextPlatformNode not crash (flutter/engine#37735) * 446a09dfc [macOS] Use consistent filenames for tests (flutter/engine#37755) * 7a390f97c Roll Skia from f1f59de17204 to 12f01bc5b57e (1 revision) (flutter/engine#37760)
…lutter#115672) * a76ec9158 Roll Fuchsia Linux SDK from lnmSnyJi-2H07tBnV... to WdtwlLEce90PjFJ9z... (flutter/engine#37747) * 44e2f5854 [Impeller] Change texture upload pipeline in Vulkan (flutter/engine#37623) * 6a3ad3c14 Roll Skia from 345bceacd298 to 5270b1d26b5f (4 revisions) (flutter/engine#37748) * 01271891c Do not abort if a MultiFrameCodec is unable to allocate a bitmap buffer (flutter/engine#37534) * 54232a4c3 Roll Skia from 5270b1d26b5f to cf967e6b1c00 (5 revisions) (flutter/engine#37751) * 30aa3cc38 [fuchsia][a11y] Set explicit hit regions in flatland embedder (flutter/engine#37338) * da07c33d2 Make NotifyIdle reject close and past deadlines. (flutter/engine#37737) * e3844cc1e Add third_party/dart/third_party/binaryen/src as a dependency (flutter/engine#37749) * aeb2cd95b [Impeller] use SSBOs for gradients where supported (metal/vulkan) (flutter/engine#37654) * e8aa1c192 Roll Skia from cf967e6b1c00 to f1f59de17204 (2 revisions) (flutter/engine#37756) * 4311774fb [Impeller] register modern shaders on Vulkan too (flutter/engine#37757) * 8e4a718d0 Made FlutterTextField that outlive FlutterTextPlatformNode not crash (flutter/engine#37735) * 446a09dfc [macOS] Use consistent filenames for tests (flutter/engine#37755) * 7a390f97c Roll Skia from f1f59de17204 to 12f01bc5b57e (1 revision) (flutter/engine#37760)
…lutter#115672) * a76ec9158 Roll Fuchsia Linux SDK from lnmSnyJi-2H07tBnV... to WdtwlLEce90PjFJ9z... (flutter/engine#37747) * 44e2f5854 [Impeller] Change texture upload pipeline in Vulkan (flutter/engine#37623) * 6a3ad3c14 Roll Skia from 345bceacd298 to 5270b1d26b5f (4 revisions) (flutter/engine#37748) * 01271891c Do not abort if a MultiFrameCodec is unable to allocate a bitmap buffer (flutter/engine#37534) * 54232a4c3 Roll Skia from 5270b1d26b5f to cf967e6b1c00 (5 revisions) (flutter/engine#37751) * 30aa3cc38 [fuchsia][a11y] Set explicit hit regions in flatland embedder (flutter/engine#37338) * da07c33d2 Make NotifyIdle reject close and past deadlines. (flutter/engine#37737) * e3844cc1e Add third_party/dart/third_party/binaryen/src as a dependency (flutter/engine#37749) * aeb2cd95b [Impeller] use SSBOs for gradients where supported (metal/vulkan) (flutter/engine#37654) * e8aa1c192 Roll Skia from cf967e6b1c00 to f1f59de17204 (2 revisions) (flutter/engine#37756) * 4311774fb [Impeller] register modern shaders on Vulkan too (flutter/engine#37757) * 8e4a718d0 Made FlutterTextField that outlive FlutterTextPlatformNode not crash (flutter/engine#37735) * 446a09dfc [macOS] Use consistent filenames for tests (flutter/engine#37755) * 7a390f97c 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.