-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] attempt to get validation errors from CI unittests. #51341
Changes from 20 commits
f86860c
e06c9c9
dcd1c5e
29c7edc
408e7f5
be3271b
43e202a
1c05893
1cecd26
d72221b
fd68de3
a453f7f
ab9a072
26dc17f
4e2eeac
2cf6407
79231ec
9e378b1
b8bcfcb
f3ee710
eea1bce
7917811
fb6e3ee
b7031ba
a38397f
de0fa35
2d6fdfb
c7f4b80
dfa2b37
dfd121f
a8f9e41
1a2b88d
7b6514c
bf9d430
50fcdde
412912b
2cec37c
34ce5b6
c53ff77
50cfa9d
3d105f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |
| // found in the LICENSE file. | ||
|
|
||
| #include "impeller/playground/playground_impl.h" | ||
| #include "flutter/testing/testing.h" | ||
|
|
||
| #define GLFW_INCLUDE_NONE | ||
| #include "third_party/glfw/include/GLFW/glfw3.h" | ||
|
|
@@ -19,6 +20,57 @@ | |
| #include "impeller/playground/backend/vulkan/playground_impl_vk.h" | ||
| #endif // IMPELLER_ENABLE_VULKAN | ||
|
|
||
| namespace { | ||
| static const std::vector<std::string> kVulkanDenyValidationTests = { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's share this instead of duplicating it twice.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| "impeller_Play_GaussianBlurFilterContentsTest_" | ||
| "RenderCoverageMatchesGetCoverageRotated_Vulkan", | ||
| "impeller_Play_SceneTest_FlutterLogo_Vulkan", | ||
| "impeller_Play_SceneTest_CuboidUnlit_Vulkan", | ||
| "impeller_Play_EntityTest_SpecializationConstantsAreAppliedToVariants_" | ||
| "Vulkan", | ||
| "impeller_Play_RuntimeStageTest_CanCreatePipelineFromRuntimeStage_Vulkan", | ||
| "impeller_Play_GaussianBlurFilterContentsTest_" | ||
| "TextureContentsWithEffectTransform_Vulkan", | ||
| "impeller_Play_GaussianBlurFilterContentsTest_" | ||
| "RenderCoverageMatchesGetCoverageTranslate_Vulkan", | ||
| "impeller_Play_GaussianBlurFilterContentsTest_" | ||
| "RenderCoverageMatchesGetCoverageRotated_Vulkan", | ||
| "impeller_Play_GaussianBlurFilterContentsTest_" | ||
| "TextureContentsWithDestinationRect_Vulkan", | ||
| "impeller_Play_EntityTest_RuntimeEffect_Vulkan", | ||
| "impeller_Play_GaussianBlurFilterContentsTest_" | ||
| "RenderCoverageMatchesGetCoverage_Vulkan", | ||
| "impeller_Play_RendererDartTest_canReflectUniformStructs_Vulkan", | ||
| "impeller_Play_RendererDartTest_canCreateRenderPassAndSubmit_Vulkan", | ||
| "impeller_Play_EntityTest_RuntimeEffectSetsRightSizeWhenUniformIsStruct_" | ||
| "Vulkan", | ||
| "impeller_Play_GaussianBlurFilterContentsTest_" | ||
| "TextureContentsWithDestinationRectScaled_Vulkan", | ||
| "impeller_Play_EntityTest_DecalSpecializationAppliedToMorphologyFilter_" | ||
| "Vulkan"}; | ||
|
|
||
| std::string GetTestName() { | ||
| std::string suite_name = | ||
| ::testing::UnitTest::GetInstance()->current_test_suite()->name(); | ||
| std::string test_name = | ||
| ::testing::UnitTest::GetInstance()->current_test_info()->name(); | ||
| std::stringstream ss; | ||
| ss << "impeller_" << suite_name << "_" << test_name; | ||
| std::string result = ss.str(); | ||
| // Make sure there are no slashes in the test name. | ||
| std::replace(result.begin(), result.end(), '/', '_'); | ||
| return result; | ||
| } | ||
|
|
||
| bool ShouldTestHaveVulkanValidations() { | ||
| std::string test_name = GetTestName(); | ||
| FML_LOG(ERROR) << "Checking: " << test_name; | ||
| return std::find(kVulkanDenyValidationTests.begin(), | ||
| kVulkanDenyValidationTests.end(), | ||
| test_name) == kVulkanDenyValidationTests.end(); | ||
| } | ||
| } // namespace | ||
|
|
||
| namespace impeller { | ||
|
|
||
| std::unique_ptr<PlaygroundImpl> PlaygroundImpl::Create( | ||
|
|
@@ -35,6 +87,7 @@ std::unique_ptr<PlaygroundImpl> PlaygroundImpl::Create( | |
| #endif // IMPELLER_ENABLE_OPENGLES | ||
| #if IMPELLER_ENABLE_VULKAN | ||
| case PlaygroundBackend::kVulkan: | ||
| switches.enable_vulkan_validation = ShouldTestHaveVulkanValidations(); | ||
| return std::make_unique<PlaygroundImplVK>(switches); | ||
| #endif // IMPELLER_ENABLE_VULKAN | ||
| default: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,7 +41,7 @@ CapabilitiesVK::CapabilitiesVK(bool enable_validations) { | |
| validations_enabled_ = | ||
| enable_validations && HasLayer("VK_LAYER_KHRONOS_validation"); | ||
| if (enable_validations && !validations_enabled_) { | ||
| FML_LOG(ERROR) | ||
| FML_LOG(FATAL) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the safer thing is to add a test that makes sure this doesn't get printed out. I'm concerned about sending users down this path on accident.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now I'm keeping this fatal for testing. So we have two approaches here:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I'm doing for impeller validations is that it is off by default (existing behavior) but I swap it on in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm moving this back to error, as a follow up we need to make sure accidentally turning off validations causes a test somewhere to fail - ideally once for each shard.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| << "Requested Impeller context creation with validations but the " | ||
| "validation layers could not be found. Expect no Vulkan validation " | ||
| "checks!"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,19 +19,12 @@ declare_args() { | |
|
|
||
| # Whether the OpenGLES backend is enabled. | ||
| impeller_enable_opengles = | ||
| (is_linux || is_win || is_android) && target_os != "fuchsia" | ||
| (is_linux || is_win || is_android || is_mac) && target_os != "fuchsia" | ||
|
|
||
| # Whether the Vulkan backend is enabled. | ||
| impeller_enable_vulkan = (is_linux || is_win || is_android || | ||
| impeller_enable_vulkan = (is_linux || is_win || is_android || is_mac || | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does this one have
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets try it |
||
| enable_unittests) && target_os != "fuchsia" | ||
|
|
||
| # Whether playgrounds should run with Vulkan. | ||
| # | ||
| # impeller_enable_vulkan may be true in build environments that run tests but | ||
| # do not have a Vulkan ICD present. | ||
| impeller_enable_vulkan_playgrounds = | ||
| (is_linux || is_win || is_android) && target_os != "fuchsia" | ||
|
|
||
| # Whether to use a prebuilt impellerc. | ||
| # If this is the empty string, impellerc will be built. | ||
| # If it is non-empty, it should be the absolute path to impellerc. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -172,6 +172,30 @@ def find_executable_path(path): | |
| raise Exception('Executable %s does not exist!' % path) | ||
|
|
||
|
|
||
| def metal_validation_env(build_dir): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This contains both Metal and Vulkan configuration variables. Rename this to Or have the caller create a merged dictionary from
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| extra_env = { | ||
| # pylint: disable=line-too-long | ||
| # See https://developer.apple.com/documentation/metal/diagnosing_metal_programming_issues_early?language=objc | ||
| 'MTL_SHADER_VALIDATION': '1', # Enables all shader validation tests. | ||
| 'MTL_SHADER_VALIDATION_GLOBAL_MEMORY': | ||
| '1', # Validates accesses to device and constant memory. | ||
| 'MTL_SHADER_VALIDATION_THREADGROUP_MEMORY': '1', # Validates accesses to threadgroup memory. | ||
| 'MTL_SHADER_VALIDATION_TEXTURE_USAGE': '1', # Validates that texture references are not nil. | ||
| # Note: built from //third_party/swiftshader | ||
| 'VK_ICD_FILENAMES': os.path.join(build_dir, 'vk_swiftshader_icd.json'), | ||
| # Note: built from //third_party/vulkan_validation_layers:vulkan_gen_json_files | ||
| # and //third_party/vulkan_validation_layers. | ||
| 'VK_LAYER_PATH': os.path.join(build_dir, 'vulkan-data'), | ||
| 'VK_INSTANCE_LAYERS': 'VK_LAYER_KHRONOS_validation', | ||
| } | ||
| if is_aarm64(): | ||
| extra_env.update({ | ||
| 'METAL_DEBUG_ERROR_MODE': '0', # Enables metal validation. | ||
| 'METAL_DEVICE_WRAPPER_TYPE': '1', # Enables metal validation. | ||
| }) | ||
| return extra_env | ||
|
|
||
|
|
||
| def build_engine_executable_command( | ||
| build_dir, executable_name, flags=None, coverage=False, gtest=False | ||
| ): | ||
|
|
@@ -474,28 +498,7 @@ def make_test(name, flags=None, extra_env=None): | |
| shuffle_flags, | ||
| coverage=coverage | ||
| ) | ||
| extra_env = { | ||
| # pylint: disable=line-too-long | ||
| # See https://developer.apple.com/documentation/metal/diagnosing_metal_programming_issues_early?language=objc | ||
| 'MTL_SHADER_VALIDATION': '1', # Enables all shader validation tests. | ||
| 'MTL_SHADER_VALIDATION_GLOBAL_MEMORY': | ||
| '1', # Validates accesses to device and constant memory. | ||
| 'MTL_SHADER_VALIDATION_THREADGROUP_MEMORY': | ||
| '1', # Validates accesses to threadgroup memory. | ||
| 'MTL_SHADER_VALIDATION_TEXTURE_USAGE': | ||
| '1', # Validates that texture references are not nil. | ||
| # Note: built from //third_party/swiftshader | ||
| 'VK_ICD_FILENAMES': os.path.join(build_dir, 'vk_swiftshader_icd.json'), | ||
| # Note: built from //third_party/vulkan_validation_layers:vulkan_gen_json_files | ||
| # and //third_party/vulkan_validation_layers. | ||
| 'VK_LAYER_PATH': os.path.join(build_dir, 'vulkan-data'), | ||
| 'VK_INSTANCE_LAYERS': 'VK_LAYER_KHRONOS_validation', | ||
| } | ||
| if is_aarm64(): | ||
| extra_env.update({ | ||
| 'METAL_DEBUG_ERROR_MODE': '0', # Enables metal validation. | ||
| 'METAL_DEVICE_WRAPPER_TYPE': '1', # Enables metal validation. | ||
| }) | ||
| extra_env = metal_validation_env(build_dir) | ||
| mac_impeller_unittests_flags = shuffle_flags + [ | ||
| '--enable_vulkan_validation', | ||
| '--gtest_filter=-*OpenGLES' # These are covered in the golden tests. | ||
|
|
@@ -543,7 +546,8 @@ def make_test(name, flags=None, extra_env=None): | |
| shuffle_flags + [ | ||
| '--enable_vulkan_validation', | ||
| # TODO(https://github.com/flutter/flutter/issues/142642): Remove this. | ||
| '--gtest_filter=-*OpenGLES', | ||
| # TODO EVEN MORE | ||
| '--gtest_filter=*Metal', | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The vulkan variants crash, I think this is because they weren't running before? I'd need to double check. Either that or they are just hitting validation checks that are fatal in a way the test harness can't handle |
||
| ], | ||
| coverage=coverage, | ||
| extra_env=extra_env, | ||
|
|
@@ -1035,8 +1039,10 @@ def run_impeller_golden_tests(build_dir: str): | |
| ) | ||
| harvester_path: Path = Path(SCRIPT_DIR).parent.joinpath('tools' | ||
| ).joinpath('golden_tests_harvester') | ||
|
|
||
| with tempfile.TemporaryDirectory(prefix='impeller_golden') as temp_dir: | ||
| run_cmd([tests_path, f'--working_dir={temp_dir}'], cwd=build_dir) | ||
| extra_env = metal_validation_env(build_dir) | ||
| run_cmd([tests_path, f'--working_dir={temp_dir}'], cwd=build_dir, env=extra_env) | ||
| dart_bin = os.path.join(build_dir, 'dart-sdk', 'bin', 'dart') | ||
| golden_path = os.path.join('testing', 'impeller_golden_tests_output.txt') | ||
| script_path = os.path.join('tools', 'dir_contents_diff', 'bin', 'dir_contents_diff.dart') | ||
|
|
||
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.
Ideally this would be a static function that returns
StatusOr<std::unique_ptr<PlaygroundImplVK>>instead of short circuiting a constructor, leaving a half initialized object.https://google.github.io/styleguide/cppguide.html#Doing_Work_in_Constructors
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 we can just lift the check out of the constructor, since its a static method. I made this an FML_CHECK
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