diff --git a/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg b/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg
new file mode 100644
index 0000000000..7c7a7b85bd
--- /dev/null
+++ b/Assets/Editor/Icons/AssetBrowser/Collapse_All.svg
@@ -0,0 +1,14 @@
+
+
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py
index 8f179f7f50..b5c00a53b7 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/ShapeIntersectionFilter_FilterStageToggle.py
@@ -68,7 +68,7 @@ def ShapeIntersectionFilter_FilterStageToggle():
# Create a new entity as a child of the vegetation area entity with Box Shape
box = hydra.Entity("box")
box.create_entity(position, ["Box Shape"])
- box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(8.0, 8.0, 1.0))
+ box.get_set_test(0, "Box Shape|Box Configuration|Dimensions", math.Vector3(5.0, 5.0, 1.0))
# Create a new entity as a child of the vegetation area entity with Cylinder Shape.
cylinder = hydra.Entity("cylinder")
@@ -80,10 +80,10 @@ def ShapeIntersectionFilter_FilterStageToggle():
# On the Shape Intersection Filter component, click the crosshair button, and add child entities one by one
vegetation.get_set_test(3, "Configuration|Shape Entity Id", box.id)
- result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 8.0, 100), 2.0)
+ result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 49), 2.0)
Report.result(Tests.instance_count_in_box_shape, result)
vegetation.get_set_test(3, "Configuration|Shape Entity Id", cylinder.id)
- result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 100), 2.0)
+ result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 121), 2.0)
Report.result(Tests.instance_count_in_cylinder_shape, result)
# Create a new entity as a child of the area entity with Random Noise Gradient, Gradient Transform Modifier,
@@ -98,12 +98,13 @@ def ShapeIntersectionFilter_FilterStageToggle():
# Pin the Random Noise entity to the Gradient Entity Id field of the Position Modifier's Gradient X
vegetation.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", random_noise.id)
- # Toggle between PreProcess and PostProcess
+ # Toggle between PreProcess and PostProcess and validate instances. Validate in a 0.3m wider radius due to position
+ # offsets
vegetation.get_set_test(3, "Configuration|Filter Stage", 1)
- result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 117), 2.0)
+ result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 121), 2.0)
Report.result(Tests.preprocess_instance_count, result)
vegetation.get_set_test(3, "Configuration|Filter Stage", 2)
- result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.0, 122), 2.0)
+ result = helper.wait_for_condition(lambda: dynveg.validate_instance_count(position, 5.3, 122), 2.0)
Report.result(Tests.postprocess_instance_count, result)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py
index af1c187817..5b1e504442 100644
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Main_Optimized.py
@@ -131,7 +131,6 @@ class TestAutomation_PrefabNotEnabled(EditorTestSuite):
class test_ShapeIntersectionFilter_InstancesPlantInAssignedShape(EditorParallelTest):
from .EditorScripts import ShapeIntersectionFilter_InstancesPlantInAssignedShape as test_module
- @pytest.mark.skip("https://github.com/o3de/o3de/issues/6973")
class test_ShapeIntersectionFilter_FilterStageToggle(EditorParallelTest):
from .EditorScripts import ShapeIntersectionFilter_FilterStageToggle as test_module
diff --git a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp
index baa287e47f..73c3d6f9ed 100644
--- a/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp
+++ b/Code/Editor/AssetImporter/AssetImporterManager/AssetImporterManager.cpp
@@ -191,6 +191,7 @@ void AssetImporterManager::OnBrowseDestinationFilePath(QLineEdit* destinationLin
fileDialog.setViewMode(QFileDialog::List);
fileDialog.setWindowModality(Qt::WindowModality::ApplicationModal);
fileDialog.setWindowTitle(tr("Select import destination"));
+ fileDialog.setFileMode(QFileDialog::Directory);
QSettings settings;
QString currentDestination = settings.value(AssetImporterManagerPrivate::g_selectDestinationFilesPath).toString();
diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp
index a7faea36f6..36e08982a7 100644
--- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp
+++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp
@@ -32,6 +32,15 @@ AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZ_CVAR_EXTERNED(bool, ed_useNewAssetBrowserTableView);
+namespace AzToolsFramework
+{
+ namespace AssetBrowser
+ {
+ static constexpr const char* CollapseAllIcon = "Assets/Editor/Icons/AssetBrowser/Collapse_All.svg";
+ static constexpr const char* MenuIcon = ":/Menu/menu.svg";
+ } // namespace AssetBrowser
+} // namespace AzToolsFramework
+
class ListenerForShowAssetEditorEvent
: public QObject
, private AzToolsFramework::EditorEvents::Bus::Handler
@@ -87,10 +96,21 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent)
m_assetBrowserModel->SetFilterModel(m_filterModel.data());
+ m_ui->m_collapseAllButton->setAutoRaise(true); // hover highlight
+ m_ui->m_collapseAllButton->setIcon(QIcon(AzAssetBrowser::CollapseAllIcon));
+
+ connect(
+ m_ui->m_collapseAllButton, &QToolButton::clicked, this,
+ [this]()
+ {
+ m_ui->m_assetBrowserTreeViewWidget->collapseAll();
+ });
+
if (ed_useNewAssetBrowserTableView)
{
m_ui->m_toggleDisplayViewBtn->setVisible(true);
- m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(":/Menu/menu.svg"));
+ m_ui->m_toggleDisplayViewBtn->setAutoRaise(true);
+ m_ui->m_toggleDisplayViewBtn->setIcon(QIcon(AzAssetBrowser::MenuIcon));
m_tableModel->setFilterRole(Qt::DisplayRole);
m_tableModel->setSourceModel(m_filterModel.data());
diff --git a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui
index a345438aed..2cc7c57ccd 100644
--- a/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui
+++ b/Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui
@@ -72,6 +72,22 @@
+ -
+
+
+ Qt::ClickFocus
+
+
+
+
+
+ 3
+
+
+
+
+
+
-
@@ -143,15 +159,6 @@
true
-
- false
-
-
- true
-
-
- false
-
-
diff --git a/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h b/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h
index e8efce1133..e99f29e051 100644
--- a/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h
+++ b/Code/Framework/AzCore/Platform/Android/AzCore/AzCore_Traits_Android.h
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 1
-#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp
index 92a80b0d9a..e89c46bce7 100644
--- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp
+++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Debug/Trace_UnixLike.cpp
@@ -6,74 +6,121 @@
*
*/
+#include
+#include
#include
#include
-#include
#include
-#include
-namespace AZ::Debug::Platform
+namespace AZ::Debug
{
#if defined(AZ_ENABLE_DEBUG_TOOLS)
- bool performDebuggerDetection()
+ void ExceptionHandler(int signal);
+#endif
+
+ constexpr int MaxMessageLength = 4096;
+ constexpr int MaxStackLines = 100;
+
+ namespace Platform
{
- AZ::IO::SystemFile processStatusFile;
- if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY))
+#if defined(AZ_ENABLE_DEBUG_TOOLS)
+ bool performDebuggerDetection()
{
- return false;
- }
-
- char buffer[4096];
- AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer);
-
- const AZStd::string_view processStatusView(buffer, buffer + numRead);
- constexpr AZStd::string_view tracerPidString = "TracerPid:";
- const size_t tracerPidOffset = processStatusView.find(tracerPidString);
- if (tracerPidOffset == AZStd::string_view::npos)
- {
- return false;
- }
- for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i)
- {
- if (!::isspace(processStatusView[i]))
+ AZ::IO::SystemFile processStatusFile;
+ if (!processStatusFile.Open("/proc/self/status", AZ::IO::SystemFile::SF_OPEN_READ_ONLY))
{
- return processStatusView[i] != '0';
+ return false;
+ }
+
+ char buffer[MaxMessageLength];
+ AZ::IO::SystemFile::SizeType numRead = processStatusFile.Read(sizeof(buffer), buffer);
+
+ const AZStd::string_view processStatusView(buffer, buffer + numRead);
+ constexpr AZStd::string_view tracerPidString = "TracerPid:";
+ const size_t tracerPidOffset = processStatusView.find(tracerPidString);
+ if (tracerPidOffset == AZStd::string_view::npos)
+ {
+ return false;
+ }
+ for (size_t i = tracerPidOffset + tracerPidString.length(); i < numRead; ++i)
+ {
+ if (processStatusView[i] != ' ')
+ {
+ return processStatusView[i] != '0';
+ }
+ }
+ return false;
+ }
+
+ bool IsDebuggerPresent()
+ {
+ static bool s_detectionPerformed = false;
+ static bool s_debuggerDetected = false;
+ if (!s_detectionPerformed)
+ {
+ s_debuggerDetected = performDebuggerDetection();
+ s_detectionPerformed = true;
+ }
+ return s_debuggerDetected;
+ }
+
+ bool AttachDebugger()
+ {
+ // Not supported yet
+ AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet");
+ return false;
+ }
+
+ void HandleExceptions(bool isEnabled)
+ {
+ if (isEnabled)
+ {
+ signal(SIGSEGV, ExceptionHandler);
+ signal(SIGTRAP, ExceptionHandler);
+ signal(SIGILL, ExceptionHandler);
+ }
+ else
+ {
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGTRAP, SIG_DFL);
+ signal(SIGILL, SIG_DFL);
}
}
- return false;
- }
- bool IsDebuggerPresent()
- {
- static bool s_detectionPerformed = false;
- static bool s_debuggerDetected = false;
- if (!s_detectionPerformed)
+ void DebugBreak()
{
- s_debuggerDetected = performDebuggerDetection();
- s_detectionPerformed = true;
+ raise(SIGINT);
}
- return s_debuggerDetected;
- }
-
- bool AttachDebugger()
- {
- // Not supported yet
- AZ_Assert(false, "AttachDebugger() is not supported for Unix platform yet");
- return false;
- }
-
- void HandleExceptions(bool)
- {}
-
- void DebugBreak()
- {
- raise(SIGINT);
- }
#endif // AZ_ENABLE_DEBUG_TOOLS
- void Terminate(int exitCode)
+ void Terminate(int exitCode)
+ {
+ _exit(exitCode);
+ }
+ } // namespace Platform
+
+#if defined(AZ_ENABLE_DEBUG_TOOLS)
+ void ExceptionHandler(int signal)
{
- _exit(exitCode);
+ char message[MaxMessageLength];
+ // Trace::RawOutput
+ Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n");
+ azsnprintf(message, MaxMessageLength, "Error: signal %s: \n", strsignal(signal));
+ Debug::Trace::Instance().RawOutput(nullptr, message);
+
+ StackFrame frames[MaxStackLines];
+ SymbolStorage::StackLine stackLines[MaxStackLines];
+ SymbolStorage decoder;
+ const unsigned int numberOfFrames = StackRecorder::Record(frames, MaxStackLines);
+ decoder.DecodeFrames(frames, numberOfFrames, stackLines);
+ for (int i = 0; i < numberOfFrames; ++i)
+ {
+ azsnprintf(message, MaxMessageLength, "%s \n", stackLines[i]);
+ Debug::Trace::Instance().RawOutput(nullptr, message);
+ }
+ Debug::Trace::Instance().RawOutput(nullptr, "==================================================================\n");
}
-} // namespace AZ::Debug::Platform
+#endif
+
+} // namespace AZ::Debug
diff --git a/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h b/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h
index 59d5f3c5ed..e5e52995a1 100644
--- a/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h
+++ b/Code/Framework/AzCore/Platform/Linux/AzCore/AzCore_Traits_Linux.h
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
-#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
diff --git a/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h b/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h
index 1a3d0663e1..9a6c76fe2d 100644
--- a/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h
+++ b/Code/Framework/AzCore/Platform/Mac/AzCore/AzCore_Traits_Mac.h
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
-#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h b/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h
index 1a83aba267..71d6b395c5 100644
--- a/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h
+++ b/Code/Framework/AzCore/Platform/Windows/AzCore/AzCore_Traits_Windows.h
@@ -98,7 +98,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE INVALID_RETURN_VALUE
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 1
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
-#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 0
#define AZ_TRAIT_USE_POSIX_STRERROR_R 0
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 1
#define AZ_TRAIT_USE_WINDOWS_FILE_API 1
diff --git a/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h b/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h
index 7a75af71fb..11a0ba84e0 100644
--- a/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h
+++ b/Code/Framework/AzCore/Platform/iOS/AzCore/AzCore_Traits_iOS.h
@@ -99,7 +99,6 @@
#define AZ_TRAIT_THREAD_HARDWARE_CONCURRENCY_RETURN_VALUE static_cast(sysconf(_SC_NPROCESSORS_ONLN));
#define AZ_TRAIT_UNITTEST_NON_PREALLOCATED_HPHA_TEST 0
#define AZ_TRAIT_UNITTEST_USE_TEST_RUNNER_ENVIRONMENT 0
-#define AZ_TRAIT_USE_CRY_SIGNAL_HANDLER 1
#define AZ_TRAIT_USE_POSIX_STRERROR_R 1
#define AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS 0
#define AZ_TRAIT_USE_WINDOWS_FILE_API 0
diff --git a/Code/Legacy/CrySystem/SystemInit.cpp b/Code/Legacy/CrySystem/SystemInit.cpp
index 09bbc3773a..f3f9442322 100644
--- a/Code/Legacy/CrySystem/SystemInit.cpp
+++ b/Code/Legacy/CrySystem/SystemInit.cpp
@@ -115,43 +115,6 @@ extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExce
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
-#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
-
-#include
-#include
-void CryEngineSignalHandler(int signal)
-{
- char resolvedPath[_MAX_PATH];
-
- // it is assumed that @log@ points at the appropriate place (so for apple, to the user profile dir)
- if (AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath("@log@/crash.log", resolvedPath, _MAX_PATH))
- {
- fprintf(stderr, "Crash Signal Handler - logged to %s\n", resolvedPath);
- FILE* file = fopen(resolvedPath, "a");
- if (file)
- {
- char sTime[128];
- time_t ltime;
- time(<ime);
- struct tm* today = localtime(<ime);
- strftime(sTime, 40, "<%Y-%m-%d %H:%M:%S> ", today);
- fprintf(file, "%s: Error: signal %s:\n", sTime, strsignal(signal));
- fflush(file);
- void* array[100];
- int s = backtrace(array, 100);
- backtrace_symbols_fd(array, s, fileno(file));
- fclose(file);
- CryLogAlways("Successfully recorded crash file: '%s'", resolvedPath);
- abort();
- }
- }
-
- CryLogAlways("Could not record crash file...");
- abort();
-}
-
-#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
-
//////////////////////////////////////////////////////////////////////////
#define DEFAULT_LOG_FILENAME "@log@/Log.txt"
@@ -697,11 +660,6 @@ public:
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::Init(const SSystemInitParams& startupParams)
{
-#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
- signal(SIGSEGV, CryEngineSignalHandler);
- signal(SIGTRAP, CryEngineSignalHandler);
- signal(SIGILL, CryEngineSignalHandler);
-#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is
diff --git a/Code/Tools/ProjectManager/Source/PythonBindings.cpp b/Code/Tools/ProjectManager/Source/PythonBindings.cpp
index 7c436a3a70..60959d4090 100644
--- a/Code/Tools/ProjectManager/Source/PythonBindings.cpp
+++ b/Code/Tools/ProjectManager/Source/PythonBindings.cpp
@@ -408,7 +408,7 @@ namespace O3DE::ProjectManager
}
// check if engine path is registered
- auto allEngines = m_manifest.attr("get_engines")();
+ auto allEngines = m_manifest.attr("get_manifest_engines")();
if (pybind11::isinstance(allEngines))
{
const AZ::IO::FixedMaxPath enginePathFixed(Py_To_String(enginePath));
@@ -891,7 +891,7 @@ namespace O3DE::ProjectManager
bool result = ExecuteWithLock([&] {
// external projects
- for (auto path : m_manifest.attr("get_projects")())
+ for (auto path : m_manifest.attr("get_manifest_projects")())
{
projects.push_back(ProjectInfoFromPath(path));
}
diff --git a/Gems/Atom/Asset/ImageProcessingAtom/gem.json b/Gems/Atom/Asset/ImageProcessingAtom/gem.json
index c2af4b7e7e..baa46268b3 100644
--- a/Gems/Atom/Asset/ImageProcessingAtom/gem.json
+++ b/Gems/Atom/Asset/ImageProcessingAtom/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Image processing for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/Bootstrap/gem.json b/Gems/Atom/Bootstrap/gem.json
index 543efe0f34..726021235f 100644
--- a/Gems/Atom/Bootstrap/gem.json
+++ b/Gems/Atom/Bootstrap/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Atom Bootstrap",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/Component/DebugCamera/gem.json b/Gems/Atom/Component/DebugCamera/gem.json
index 74d88a21b6..678cce3045 100644
--- a/Gems/Atom/Component/DebugCamera/gem.json
+++ b/Gems/Atom/Component/DebugCamera/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Debug Camera component for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/Feature/Common/gem.json b/Gems/Atom/Feature/Common/gem.json
index f4c936dc4a..d915c55b1d 100644
--- a/Gems/Atom/Feature/Common/gem.json
+++ b/Gems/Atom/Feature/Common/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Common features for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/RHI/DX12/gem.json b/Gems/Atom/RHI/DX12/gem.json
index 803ae4f4d0..67d91790a9 100644
--- a/Gems/Atom/RHI/DX12/gem.json
+++ b/Gems/Atom/RHI/DX12/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "DX12 RHI for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/RHI/Metal/gem.json b/Gems/Atom/RHI/Metal/gem.json
index 0257048bd3..555b86523c 100644
--- a/Gems/Atom/RHI/Metal/gem.json
+++ b/Gems/Atom/RHI/Metal/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Metal RHI for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/RHI/Null/gem.json b/Gems/Atom/RHI/Null/gem.json
index 1ea2eb4cb0..d531aa4ab5 100644
--- a/Gems/Atom/RHI/Null/gem.json
+++ b/Gems/Atom/RHI/Null/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Atom Null RHI",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/RHI/Vulkan/gem.json b/Gems/Atom/RHI/Vulkan/gem.json
index 508ad85c75..5d49085ac5 100644
--- a/Gems/Atom/RHI/Vulkan/gem.json
+++ b/Gems/Atom/RHI/Vulkan/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Vulcan RHI for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/RHI/gem.json b/Gems/Atom/RHI/gem.json
index 858a64fc17..49ec18ea53 100644
--- a/Gems/Atom/RHI/gem.json
+++ b/Gems/Atom/RHI/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "RHI for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/RPI/gem.json b/Gems/Atom/RPI/gem.json
index 0acef5179b..fe135c3e90 100644
--- a/Gems/Atom/RPI/gem.json
+++ b/Gems/Atom/RPI/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "RPI for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/Atom/Tools/AtomToolsFramework/gem.json b/Gems/Atom/Tools/AtomToolsFramework/gem.json
index 6e5a7b311a..a86244e7cc 100644
--- a/Gems/Atom/Tools/AtomToolsFramework/gem.json
+++ b/Gems/Atom/Tools/AtomToolsFramework/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Tools Framework for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/AtomBridge/gem.json b/Gems/AtomLyIntegration/AtomBridge/gem.json
index 5a8512c90d..87a10aa6d3 100644
--- a/Gems/AtomLyIntegration/AtomBridge/gem.json
+++ b/Gems/AtomLyIntegration/AtomBridge/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Atom Bridge",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/AtomFont/gem.json b/Gems/AtomLyIntegration/AtomFont/gem.json
index d979509059..4f5ba75ff2 100644
--- a/Gems/AtomLyIntegration/AtomFont/gem.json
+++ b/Gems/AtomLyIntegration/AtomFont/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Font Rendering for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json b/Gems/AtomLyIntegration/AtomImGuiTools/gem.json
index 205120f6f0..2ae8edfa57 100644
--- a/Gems/AtomLyIntegration/AtomImGuiTools/gem.json
+++ b/Gems/AtomLyIntegration/AtomImGuiTools/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Tool",
- "summary": "",
+ "summary": "ImGui tools for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json
index cff957c1f1..a7b9dab980 100644
--- a/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayIcons/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Viewport display icons for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json
index a2bc92c76d..0deeeef602 100644
--- a/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json
+++ b/Gems/AtomLyIntegration/AtomViewportDisplayInfo/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Viewport Display Information for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/CommonFeatures/gem.json b/Gems/AtomLyIntegration/CommonFeatures/gem.json
index a06f607fab..b6290679b9 100644
--- a/Gems/AtomLyIntegration/CommonFeatures/gem.json
+++ b/Gems/AtomLyIntegration/CommonFeatures/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "Common features for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json b/Gems/AtomLyIntegration/EMotionFXAtom/gem.json
index 8bea93da91..3847432cf7 100644
--- a/Gems/AtomLyIntegration/EMotionFXAtom/gem.json
+++ b/Gems/AtomLyIntegration/EMotionFXAtom/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "EmotionFX for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/AtomLyIntegration/ImguiAtom/gem.json b/Gems/AtomLyIntegration/ImguiAtom/gem.json
index 4c65d80e33..70ff1c0414 100644
--- a/Gems/AtomLyIntegration/ImguiAtom/gem.json
+++ b/Gems/AtomLyIntegration/ImguiAtom/gem.json
@@ -6,7 +6,7 @@
"origin": "Open 3D Engine - o3de.org",
"origin_url": "https://github.com/o3de/o3de",
"type": "Code",
- "summary": "",
+ "summary": "ImGui support for Atom",
"canonical_tags": [
"Gem"
],
diff --git a/Gems/FastNoise/Code/CMakeLists.txt b/Gems/FastNoise/Code/CMakeLists.txt
index 819592e018..d945db1665 100644
--- a/Gems/FastNoise/Code/CMakeLists.txt
+++ b/Gems/FastNoise/Code/CMakeLists.txt
@@ -104,7 +104,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
NAME FastNoise.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
NAMESPACE Gem
FILES_CMAKE
- fastnoise_tests_files.cmake
+ fastnoise_editor_tests_files.cmake
COMPILE_DEFINITIONS
PUBLIC
FASTNOISE_EDITOR
@@ -120,23 +120,31 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_googletest(
NAME Gem::FastNoise.Editor.Tests
)
- else()
- ly_add_target(
- NAME FastNoise.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
- NAMESPACE Gem
- FILES_CMAKE
- fastnoise_tests_files.cmake
- INCLUDE_DIRECTORIES
- PRIVATE
- Tests
- BUILD_DEPENDENCIES
- PRIVATE
- AZ::AzTest
- Gem::FastNoise.Static
- Gem::LmbrCentral
- )
- ly_add_googletest(
- NAME Gem::FastNoise.Tests
- )
endif()
+
+ ly_add_target(
+ NAME FastNoise.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
+ NAMESPACE Gem
+ FILES_CMAKE
+ fastnoise_tests_files.cmake
+ INCLUDE_DIRECTORIES
+ PRIVATE
+ Tests
+ BUILD_DEPENDENCIES
+ PRIVATE
+ AZ::AzTest
+ Gem::FastNoise.Static
+ Gem::GradientSignal
+ Gem::GradientSignal.Tests.Static
+ Gem::LmbrCentral
+ )
+ ly_add_googletest(
+ NAME Gem::FastNoise.Tests
+ )
+
+ ly_add_googlebenchmark(
+ NAME Gem::FastNoise.Benchmarks
+ TARGET Gem::FastNoise.Tests
+ )
+
endif()
diff --git a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp
index 4cea2efcc8..ceeafc3af6 100644
--- a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp
+++ b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.cpp
@@ -54,6 +54,21 @@ namespace FastNoiseGem
return AZ::Edit::PropertyVisibility::Hide;
}
+ bool FastNoiseGradientConfig::operator==(const FastNoiseGradientConfig& rhs) const
+ {
+ return (m_cellularDistanceFunction == rhs.m_cellularDistanceFunction)
+ && (m_cellularJitter == rhs.m_cellularJitter)
+ && (m_cellularReturnType == rhs.m_cellularReturnType)
+ && (m_fractalType == rhs.m_fractalType)
+ && (m_frequency == rhs.m_frequency)
+ && (m_gain == rhs.m_gain)
+ && (m_interp == rhs.m_interp)
+ && (m_lacunarity == rhs.m_lacunarity)
+ && (m_noiseType == rhs.m_noiseType)
+ && (m_octaves == rhs.m_octaves)
+ && (m_seed == rhs.m_seed);
+ }
+
void FastNoiseGradientConfig::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast(context))
@@ -306,7 +321,7 @@ namespace FastNoiseGem
float FastNoiseGradientComponent::GetValue(const GradientSignal::GradientSampleParams& sampleParams) const
{
- AZ::Vector3 uvw = sampleParams.m_position;
+ AZ::Vector3 uvw;
bool wasPointRejected = false;
{
@@ -314,13 +329,34 @@ namespace FastNoiseGem
m_gradientTransform.TransformPositionToUVW(sampleParams.m_position, uvw, wasPointRejected);
}
- if (!wasPointRejected)
+ // Generator returns a range between [-1, 1], map that to [0, 1]
+ return wasPointRejected ?
+ 0.0f :
+ AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f);
+ }
+
+ void FastNoiseGradientComponent::GetValues(AZStd::span positions, AZStd::span outValues) const
+ {
+ if (positions.size() != outValues.size())
{
- // Generator returns a range between [-1, 1], map that to [0, 1]
- return AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f);
+ AZ_Assert(false, "input and output lists are different sizes (%zu vs %zu).", positions.size(), outValues.size());
+ return;
}
- return 0.0f;
+ AZStd::shared_lock lock(m_transformMutex);
+ AZ::Vector3 uvw;
+
+ for (size_t index = 0; index < positions.size(); index++)
+ {
+ bool wasPointRejected = false;
+
+ m_gradientTransform.TransformPositionToUVW(positions[index], uvw, wasPointRejected);
+
+ // Generator returns a range between [-1, 1], map that to [0, 1]
+ outValues[index] = wasPointRejected ?
+ 0.0f :
+ AZ::GetClamp((m_generator.GetNoise(uvw.GetX(), uvw.GetY(), uvw.GetZ()) + 1.0f) / 2.0f, 0.0f, 1.0f);
+ }
}
template
diff --git a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h
index dd19049ee6..29c42bfe1b 100644
--- a/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h
+++ b/Gems/FastNoise/Code/Source/FastNoiseGradientComponent.h
@@ -47,6 +47,8 @@ namespace FastNoiseGem
AZ::u32 GetFrequencyParameterVisbility() const;
AZ::u32 GetInterpParameterVisibility() const;
+ bool operator==(const FastNoiseGradientConfig& rhs) const;
+
int m_seed = 1;
float m_frequency = 1.f;
FastNoise::Interp m_interp = FastNoise::Interp::Quintic;
@@ -90,6 +92,7 @@ namespace FastNoiseGem
// GradientRequestBus overrides...
float GetValue(const GradientSignal::GradientSampleParams& sampleParams) const override;
+ void GetValues(AZStd::span positions, AZStd::span outValues) const override;
protected:
FastNoiseGradientConfig m_configuration;
diff --git a/Gems/FastNoise/Code/Tests/FastNoiseBenchmarks.cpp b/Gems/FastNoise/Code/Tests/FastNoiseBenchmarks.cpp
new file mode 100644
index 0000000000..1e438db112
--- /dev/null
+++ b/Gems/FastNoise/Code/Tests/FastNoiseBenchmarks.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#ifdef HAVE_BENCHMARK
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace UnitTest
+{
+ class FastNoiseGetValues
+ : public ::benchmark::Fixture
+ {
+ public:
+ void RunGetValueOrGetValuesBenchmark(benchmark::State& state, FastNoise::NoiseType noiseType)
+ {
+ AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
+ ASSERT_TRUE(noiseEntity != nullptr);
+ noiseEntity->CreateComponent();
+ noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
+ noiseEntity->CreateComponent();
+
+ // Set up a FastNoise component with the requested noise type
+ FastNoiseGem::FastNoiseGradientConfig cfg;
+ cfg.m_frequency = 0.01f;
+ cfg.m_noiseType = noiseType;
+ noiseEntity->CreateComponent(cfg);
+
+ noiseEntity->Init();
+ noiseEntity->Activate();
+
+ UnitTest::GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, noiseEntity->GetId());
+ }
+
+ };
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Value)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Value);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_ValueFractal)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::ValueFractal);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Perlin)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Perlin);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_PerlinFractal)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::PerlinFractal);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Simplex)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Simplex);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_SimplexFractal)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::SimplexFractal);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Cellular)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Cellular);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_WhiteNoise)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::WhiteNoise);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_Cubic)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::Cubic);
+ }
+
+ BENCHMARK_DEFINE_F(FastNoiseGetValues, BM_FastNoiseGradient_CubicFractal)(benchmark::State& state)
+ {
+ RunGetValueOrGetValuesBenchmark(state, FastNoise::NoiseType::CubicFractal);
+ }
+
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Value);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_ValueFractal);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Perlin);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_PerlinFractal);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Simplex);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_SimplexFractal);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Cellular);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_WhiteNoise);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_Cubic);
+ GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(FastNoiseGetValues, BM_FastNoiseGradient_CubicFractal);
+
+#endif
+}
+
+
+
diff --git a/Gems/FastNoise/Code/Tests/FastNoiseEditorTest.cpp b/Gems/FastNoise/Code/Tests/FastNoiseEditorTest.cpp
new file mode 100644
index 0000000000..e30c6c01e0
--- /dev/null
+++ b/Gems/FastNoise/Code/Tests/FastNoiseEditorTest.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+
+class FastNoiseEditorTestApp : public ::testing::Test
+{
+};
+
+TEST_F(FastNoiseEditorTestApp, FastNoise_EditorCreateGameEntity)
+{
+ AZStd::unique_ptr noiseEntity(aznew AZ::Entity("editor_noise_entity"));
+ ASSERT_TRUE(noiseEntity != nullptr);
+
+ FastNoiseGem::EditorFastNoiseGradientComponent editor;
+ auto* editorBase = static_cast(&editor);
+ editorBase->BuildGameEntity(noiseEntity.get());
+
+ // the new game entity's FastNoise component should look like the default one
+ FastNoiseGem::FastNoiseGradientConfig defaultConfig;
+ FastNoiseGem::FastNoiseGradientConfig gameComponentConfig;
+
+ FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent();
+ ASSERT_TRUE(noiseComp != nullptr);
+
+ // Change a value in the gameComponentConfig just to verify that it got overwritten instead of simply matching the default.
+ gameComponentConfig.m_seed++;
+ noiseComp->WriteOutConfig(&gameComponentConfig);
+ ASSERT_EQ(defaultConfig, gameComponentConfig);
+}
+
+// This uses custom test / benchmark hooks so that we can load LmbrCentral and GradientSignal Gems.
+AZ_UNIT_TEST_HOOK(new UnitTest::FastNoiseTestEnvironment, UnitTest::FastNoiseBenchmarkEnvironment);
diff --git a/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp b/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp
index f0d5a9d1bd..1ac5e8ddca 100644
--- a/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp
+++ b/Gems/FastNoise/Code/Tests/FastNoiseTest.cpp
@@ -10,199 +10,61 @@
#include
#include
-#include
-#include
-#include
#include
+#include
#include
-#include
-#include
+#include
#include
-#include
+#include
+#include
+#include
#include
#include
#include
+#include
+#include
-class MockGradientTransformComponent
- : public AZ::Component
- , private GradientSignal::GradientTransformRequestBus::Handler
- , private GradientSignal::GradientTransformModifierRequestBus::Handler
+class FastNoiseTest : public ::testing::Test
{
-public:
- AZ_COMPONENT(MockGradientTransformComponent, "{464CF47B-7E10-4E1B-BD06-79BD2AC91399}");
-
- static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services)
- {
- services.push_back(AZ_CRC("GradientTransformService", 0x8c8c5ecc));
- }
- static void Reflect([[maybe_unused]] AZ::ReflectContext* context) {}
-
- MockGradientTransformComponent() = default;
- ~MockGradientTransformComponent() = default;
-
- // AZ::Component interface
- void Activate() override {}
- void Deactivate() override {}
-
- ////////////////////////////////////////////////////////////////////////////
- //// GradientTransformRequestBus
- const GradientSignal::GradientTransform& GetGradientTransform() const override
- {
- return m_gradientTransform;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // GradientTransformModifierRequestBus
- bool GetAllowReference() const override { return false; }
- void SetAllowReference([[maybe_unused]] bool value) override {}
-
- AZ::EntityId GetShapeReference() const override { return AZ::EntityId(); }
- void SetShapeReference([[maybe_unused]] AZ::EntityId shapeReference) override {}
-
- bool GetOverrideBounds() const override { return false; }
- void SetOverrideBounds([[maybe_unused]] bool value) override {}
-
- AZ::Vector3 GetBounds() const override { return AZ::Vector3(); }
- void SetBounds([[maybe_unused]] AZ::Vector3 bounds) override {}
-
- GradientSignal::TransformType GetTransformType() const override { return static_cast(0); }
- void SetTransformType([[maybe_unused]] GradientSignal::TransformType type) override {}
-
- bool GetOverrideTranslate() const override { return false; }
- void SetOverrideTranslate([[maybe_unused]] bool value) override {}
-
- AZ::Vector3 GetTranslate() const override { return AZ::Vector3(); }
- void SetTranslate([[maybe_unused]] AZ::Vector3 translate) override {}
-
- bool GetOverrideRotate() const override { return false; }
- void SetOverrideRotate([[maybe_unused]] bool value) override {}
-
- AZ::Vector3 GetRotate() const override { return AZ::Vector3(); }
- void SetRotate([[maybe_unused]] AZ::Vector3 rotate) override {}
-
- bool GetOverrideScale() const override { return false; }
- void SetOverrideScale([[maybe_unused]] bool value) override {}
-
- AZ::Vector3 GetScale() const override { return AZ::Vector3(); }
- void SetScale([[maybe_unused]] AZ::Vector3 scale) override {}
-
- float GetFrequencyZoom() const override { return false; }
- void SetFrequencyZoom([[maybe_unused]] float frequencyZoom) override {}
-
- GradientSignal::WrappingType GetWrappingType() const override { return static_cast(0); }
- void SetWrappingType([[maybe_unused]] GradientSignal::WrappingType type) override {}
-
- bool GetIs3D() const override { return false; }
- void SetIs3D([[maybe_unused]] bool value) override {}
-
- bool GetAdvancedMode() const override { return false; }
- void SetAdvancedMode([[maybe_unused]] bool value) override {}
-
- GradientSignal::GradientTransform m_gradientTransform;
};
-TEST(FastNoiseTest, ComponentsWithComponentApplication)
-{
- AZ::ComponentApplication::Descriptor appDesc;
- appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024;
- appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL;
- appDesc.m_stackRecordLevels = 20;
-
- AZ::ComponentApplication app;
- AZ::Entity* systemEntity = app.Create(appDesc);
- ASSERT_TRUE(systemEntity != nullptr);
- app.RegisterComponentDescriptor(FastNoiseGem::FastNoiseSystemComponent::CreateDescriptor());
- systemEntity->CreateComponent();
-
- systemEntity->Init();
- systemEntity->Activate();
-
- AZ::Entity* noiseEntity = aznew AZ::Entity("fastnoise_entity");
- noiseEntity->CreateComponent();
- app.AddEntity(noiseEntity);
-
- app.Destroy();
- ASSERT_TRUE(true);
-}
-
-class FastNoiseTestApp
- : public ::testing::Test
-{
-public:
- FastNoiseTestApp()
- : m_application()
- , m_systemEntity(nullptr)
- {
- }
-
- void SetUp() override
- {
- AZ::ComponentApplication::Descriptor appDesc;
- appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024;
- appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL;
- appDesc.m_stackRecordLevels = 20;
-
- AZ::ComponentApplication::StartupParameters appStartup;
- appStartup.m_createStaticModulesCallback =
- [](AZStd::vector& modules)
- {
- modules.emplace_back(new FastNoiseGem::FastNoiseModule);
- };
-
- m_systemEntity = m_application.Create(appDesc, appStartup);
- m_application.RegisterComponentDescriptor(MockGradientTransformComponent::CreateDescriptor());
- m_systemEntity->Init();
- m_systemEntity->Activate();
- }
-
- void TearDown() override
- {
- m_application.Destroy();
- }
-
- AZ::ComponentApplication m_application;
- AZ::Entity* m_systemEntity;
-};
-
-//////////////////////////////////////////////////////////////////////////
-// testing class to inspect protected data members in the FastNoiseGradientComponent
-struct FastNoiseGradientComponentTester : public FastNoiseGem::FastNoiseGradientComponent
-{
- const FastNoiseGem::FastNoiseGradientConfig& GetConfig() const { return m_configuration; }
-
- void AssertTrue(const FastNoiseGem::FastNoiseGradientConfig& cfg)
- {
- ASSERT_TRUE(m_configuration.m_cellularDistanceFunction == cfg.m_cellularDistanceFunction);
- ASSERT_TRUE(m_configuration.m_cellularJitter == cfg.m_cellularJitter);
- ASSERT_TRUE(m_configuration.m_cellularReturnType == cfg.m_cellularReturnType);
- ASSERT_TRUE(m_configuration.m_fractalType == cfg.m_fractalType);
- ASSERT_TRUE(m_configuration.m_frequency == cfg.m_frequency);
- ASSERT_TRUE(m_configuration.m_gain == cfg.m_gain);
- ASSERT_TRUE(m_configuration.m_interp == cfg.m_interp);
- ASSERT_TRUE(m_configuration.m_lacunarity == cfg.m_lacunarity);
- ASSERT_TRUE(m_configuration.m_noiseType == cfg.m_noiseType);
- ASSERT_TRUE(m_configuration.m_octaves == cfg.m_octaves);
- ASSERT_TRUE(m_configuration.m_seed == cfg.m_seed);
- }
-};
-
-TEST_F(FastNoiseTestApp, FastNoise_Component)
+TEST_F(FastNoiseTest, FastNoise_ComponentCreatesSuccessfully)
{
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
ASSERT_TRUE(noiseEntity != nullptr);
noiseEntity->CreateComponent();
- m_application.AddEntity(noiseEntity);
FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent();
ASSERT_TRUE(noiseComp != nullptr);
}
-TEST_F(FastNoiseTestApp, FastNoise_ComponentEbus)
+TEST_F(FastNoiseTest, FastNoise_ComponentMatchesConfiguration)
{
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
ASSERT_TRUE(noiseEntity != nullptr);
+
+ FastNoiseGem::FastNoiseGradientConfig cfg;
+ FastNoiseGem::FastNoiseGradientConfig componentConfig;
+
+ noiseEntity->CreateComponent();
+ noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
+ noiseEntity->CreateComponent();
+ noiseEntity->CreateComponent(cfg);
+
+ FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent();
+ ASSERT_TRUE(noiseComp != nullptr);
+ noiseComp->WriteOutConfig(&componentConfig);
+ ASSERT_EQ(cfg, componentConfig);
+}
+
+TEST_F(FastNoiseTest, FastNoise_ComponentEbusWorksSuccessfully)
+{
+ AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
+ ASSERT_TRUE(noiseEntity != nullptr);
+ noiseEntity->CreateComponent();
+ noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
+ noiseEntity->CreateComponent();
noiseEntity->CreateComponent();
- noiseEntity->CreateComponent();
noiseEntity->Init();
noiseEntity->Activate();
@@ -210,51 +72,39 @@ TEST_F(FastNoiseTestApp, FastNoise_ComponentEbus)
GradientSignal::GradientSampleParams params;
float sample = -1.0f;
- GradientSignal::GradientRequestBus::EventResult(sample, noiseEntity->GetId(), &GradientSignal::GradientRequestBus::Events::GetValue, params);
+ GradientSignal::GradientRequestBus::EventResult(sample, noiseEntity->GetId(),
+ &GradientSignal::GradientRequestBus::Events::GetValue, params);
ASSERT_TRUE(sample >= 0.0f);
ASSERT_TRUE(sample <= 1.0f);
}
-TEST_F(FastNoiseTestApp, FastNoise_ComponentMatchesConfiguration)
+TEST_F(FastNoiseTest, FastNoise_VerifyGetValueAndGetValuesMatch)
{
+ const float shapeHalfBounds = 128.0f;
+
AZ::Entity* noiseEntity = aznew AZ::Entity("noise_entity");
ASSERT_TRUE(noiseEntity != nullptr);
+ noiseEntity->CreateComponent();
+ noiseEntity->CreateComponent();
- AZ::SimpleLcgRandom rand(AZStd::GetTimeNowMicroSecond());
+ // Create a Box Shape to map our gradient into
+ LmbrCentral::BoxShapeConfig boxConfig(AZ::Vector3(shapeHalfBounds * 2.0f));
+ auto boxComponent = noiseEntity->CreateComponent(LmbrCentral::BoxShapeComponentTypeId);
+ boxComponent->SetConfiguration(boxConfig);
+ // Create a Fast Noise component with an adjusted frequency. (The defaults of Perlin noise with frequency=1.0 would cause us
+ // to always get back the same noise value)
FastNoiseGem::FastNoiseGradientConfig cfg;
-
+ cfg.m_frequency = 0.01f;
noiseEntity->CreateComponent(cfg);
- noiseEntity->CreateComponent();
- m_application.AddEntity(noiseEntity);
+ noiseEntity->Init();
+ noiseEntity->Activate();
- FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent();
- ASSERT_TRUE(noiseComp != nullptr);
- reinterpret_cast(noiseComp)->AssertTrue(cfg);
+ // Create a gradient sampler and run through a series of points to see if they match expectations.
+ UnitTest::GradientSignalTestHelpers::CompareGetValueAndGetValues(noiseEntity->GetId(), shapeHalfBounds);
}
-#if FASTNOISE_EDITOR
-#include
-
-TEST_F(FastNoiseTestApp, FastNoise_EditorCreateGameEntity)
-{
- AZStd::unique_ptr noiseEntity(aznew AZ::Entity("editor_noise_entity"));
- ASSERT_TRUE(noiseEntity != nullptr);
-
- FastNoiseGem::EditorFastNoiseGradientComponent editor;
- auto* editorBase = static_cast(&editor);
- editorBase->BuildGameEntity(noiseEntity.get());
-
- // the new game entity's ocean component should look like the default one
- FastNoiseGem::FastNoiseGradientConfig cfg;
-
- FastNoiseGem::FastNoiseGradientComponent* noiseComp = noiseEntity->FindComponent();
- ASSERT_TRUE(noiseComp != nullptr);
- reinterpret_cast(noiseComp)->AssertTrue(cfg);
-}
-
-#endif
-
-AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
+// This uses custom test / benchmark hooks so that we can load LmbrCentral and GradientSignal Gems.
+AZ_UNIT_TEST_HOOK(new UnitTest::FastNoiseTestEnvironment, UnitTest::FastNoiseBenchmarkEnvironment);
diff --git a/Gems/FastNoise/Code/Tests/FastNoiseTest.h b/Gems/FastNoise/Code/Tests/FastNoiseTest.h
new file mode 100644
index 0000000000..71b10cfc68
--- /dev/null
+++ b/Gems/FastNoise/Code/Tests/FastNoiseTest.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace UnitTest
+{
+ // The FastNoise unit tests need to use the GemTestEnvironment to load the GradientSignal and LmbrCentral Gems so that
+ // GradientTransform components can be used in the unit tests and benchmarks.
+ class FastNoiseTestEnvironment
+ : public AZ::Test::GemTestEnvironment
+ {
+ public:
+ void AddGemsAndComponents() override
+ {
+ AddDynamicModulePaths({ "GradientSignal" });
+ AddDynamicModulePaths({ "LmbrCentral" });
+
+ AddComponentDescriptors({
+ AzFramework::TransformComponent::CreateDescriptor(),
+ FastNoiseGem::FastNoiseSystemComponent::CreateDescriptor(),
+ FastNoiseGem::FastNoiseGradientComponent::CreateDescriptor()
+ });
+
+ AddRequiredComponents({ FastNoiseGem::FastNoiseSystemComponent::TYPEINFO_Uuid() });
+ }
+ };
+
+#ifdef HAVE_BENCHMARK
+ //! The Benchmark environment is used for one time setup and tear down of shared resources
+ class FastNoiseBenchmarkEnvironment
+ : public AZ::Test::BenchmarkEnvironmentBase
+ , public FastNoiseTestEnvironment
+
+ {
+ protected:
+ void SetUpBenchmark() override
+ {
+ SetupEnvironment();
+ }
+
+ void TearDownBenchmark() override
+ {
+ TeardownEnvironment();
+ }
+ };
+#endif
+
+
+} // namespace UnitTest
+
diff --git a/Gems/FastNoise/Code/fastnoise_editor_tests_files.cmake b/Gems/FastNoise/Code/fastnoise_editor_tests_files.cmake
new file mode 100644
index 0000000000..685e2fb647
--- /dev/null
+++ b/Gems/FastNoise/Code/fastnoise_editor_tests_files.cmake
@@ -0,0 +1,13 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+ Tests/FastNoiseEditorTest.cpp
+ Source/FastNoiseModule.h
+ Source/FastNoiseModule.cpp
+)
diff --git a/Gems/FastNoise/Code/fastnoise_tests_files.cmake b/Gems/FastNoise/Code/fastnoise_tests_files.cmake
index 08386940f2..4669b0d446 100644
--- a/Gems/FastNoise/Code/fastnoise_tests_files.cmake
+++ b/Gems/FastNoise/Code/fastnoise_tests_files.cmake
@@ -7,6 +7,7 @@
#
set(FILES
+ Tests/FastNoiseBenchmarks.cpp
Tests/FastNoiseTest.cpp
Source/FastNoiseModule.h
Source/FastNoiseModule.cpp
diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp
index bd4ccf5205..6ffb4a31c4 100644
--- a/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp
+++ b/Gems/GradientSignal/Code/Tests/GradientSignalBenchmarks.cpp
@@ -9,6 +9,7 @@
#ifdef HAVE_BENCHMARK
#include
+#include
#include
#include
@@ -21,220 +22,42 @@ namespace UnitTest
class GradientGetValues : public GradientSignalBenchmarkFixture
{
public:
- // We use an enum to list out the different types of GetValue() benchmarks to run so that way we can condense our test cases
- // to just take the value in as a benchmark argument and switch on it. Otherwise, we would need to write a different benchmark
- // function for each test case for each gradient.
- enum GetValuePermutation : int64_t
- {
- EBUS_GET_VALUE,
- EBUS_GET_VALUES,
- SAMPLER_GET_VALUE,
- SAMPLER_GET_VALUES,
- };
-
// Create an arbitrary size shape for creating our gradients for benchmark runs.
const float TestShapeHalfBounds = 128.0f;
-
- void FillQueryPositions(AZStd::vector& positions, float height, float width)
- {
- size_t index = 0;
- for (float y = 0.0f; y < height; y += 1.0f)
- {
- for (float x = 0.0f; x < width; x += 1.0f)
- {
- positions[index++] = AZ::Vector3(x, y, 0.0f);
- }
- }
- }
-
- void RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
- {
- AZ_PROFILE_FUNCTION(Entity);
-
- GradientSignal::GradientSampleParams params;
-
- // Get the height and width ranges for querying from our benchmark parameters
- const float height = aznumeric_cast(queryRange);
- const float width = aznumeric_cast(queryRange);
-
- // Call GetValue() on the EBus for every height and width in our ranges.
- for (auto _ : state)
- {
- for (float y = 0.0f; y < height; y += 1.0f)
- {
- for (float x = 0.0f; x < width; x += 1.0f)
- {
- float value = 0.0f;
- params.m_position = AZ::Vector3(x, y, 0.0f);
- GradientSignal::GradientRequestBus::EventResult(
- value, gradientId, &GradientSignal::GradientRequestBus::Events::GetValue, params);
- benchmark::DoNotOptimize(value);
- }
- }
- }
- }
-
- void RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
- {
- AZ_PROFILE_FUNCTION(Entity);
-
- // Get the height and width ranges for querying from our benchmark parameters
- float height = aznumeric_cast(queryRange);
- float width = aznumeric_cast(queryRange);
- int64_t totalQueryPoints = queryRange * queryRange;
-
- // Call GetValues() for every height and width in our ranges.
- for (auto _ : state)
- {
- // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create
- // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable.
- AZStd::vector positions(totalQueryPoints);
- FillQueryPositions(positions, height, width);
-
- // Query and get the results.
- AZStd::vector results(totalQueryPoints);
- GradientSignal::GradientRequestBus::Event(
- gradientId, &GradientSignal::GradientRequestBus::Events::GetValues, positions, results);
- }
- }
-
- void RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
- {
- AZ_PROFILE_FUNCTION(Entity);
-
- // Create a gradient sampler to use for querying our gradient.
- GradientSignal::GradientSampler gradientSampler;
- gradientSampler.m_gradientId = gradientId;
-
- // Get the height and width ranges for querying from our benchmark parameters
- const float height = aznumeric_cast(queryRange);
- const float width = aznumeric_cast(queryRange);
-
- // Call GetValue() through the GradientSampler for every height and width in our ranges.
- for (auto _ : state)
- {
- for (float y = 0.0f; y < height; y += 1.0f)
- {
- for (float x = 0.0f; x < width; x += 1.0f)
- {
- GradientSignal::GradientSampleParams params;
- params.m_position = AZ::Vector3(x, y, 0.0f);
- float value = gradientSampler.GetValue(params);
- benchmark::DoNotOptimize(value);
- }
- }
- }
- }
-
- void RunSamplerGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
- {
- AZ_PROFILE_FUNCTION(Entity);
-
- // Create a gradient sampler to use for querying our gradient.
- GradientSignal::GradientSampler gradientSampler;
- gradientSampler.m_gradientId = gradientId;
-
- // Get the height and width ranges for querying from our benchmark parameters
- const float height = aznumeric_cast(queryRange);
- const float width = aznumeric_cast(queryRange);
- const int64_t totalQueryPoints = queryRange * queryRange;
-
- // Call GetValues() through the GradientSampler for every height and width in our ranges.
- for (auto _ : state)
- {
- // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create
- // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable.
- AZStd::vector positions(totalQueryPoints);
- FillQueryPositions(positions, height, width);
-
- // Query and get the results.
- AZStd::vector results(totalQueryPoints);
- gradientSampler.GetValues(positions, results);
- }
- }
-
- void RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId)
- {
- switch (state.range(0))
- {
- case GetValuePermutation::EBUS_GET_VALUE:
- RunEBusGetValueBenchmark(state, gradientId, state.range(1));
- break;
- case GetValuePermutation::EBUS_GET_VALUES:
- RunEBusGetValuesBenchmark(state, gradientId, state.range(1));
- break;
- case GetValuePermutation::SAMPLER_GET_VALUE:
- RunSamplerGetValueBenchmark(state, gradientId, state.range(1));
- break;
- case GetValuePermutation::SAMPLER_GET_VALUES:
- RunSamplerGetValuesBenchmark(state, gradientId, state.range(1));
- break;
- default:
- AZ_Assert(false, "Benchmark permutation type not supported.");
- }
- }
};
-// Because there's no good way to label different enums in the output results (they just appear as integer values), we work around it by
-// registering one set of benchmark runs for each enum value and use ArgNames() to give it a friendly name in the results.
-#define GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(Fixture, Func) \
- BENCHMARK_REGISTER_F(Fixture, Func) \
- ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 1024 }) \
- ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 2048 }) \
- ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUE, 4096 }) \
- ->ArgNames({ "EbusGetValue", "size" }) \
- ->Unit(::benchmark::kMillisecond); \
- BENCHMARK_REGISTER_F(Fixture, Func) \
- ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 1024 }) \
- ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 2048 }) \
- ->Args({ GradientGetValues::GetValuePermutation::EBUS_GET_VALUES, 4096 }) \
- ->ArgNames({ "EbusGetValues", "size" }) \
- ->Unit(::benchmark::kMillisecond); \
- BENCHMARK_REGISTER_F(Fixture, Func) \
- ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 1024 }) \
- ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 2048 }) \
- ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUE, 4096 }) \
- ->ArgNames({ "SamplerGetValue", "size" }) \
- ->Unit(::benchmark::kMillisecond); \
- BENCHMARK_REGISTER_F(Fixture, Func) \
- ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 1024 }) \
- ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 2048 }) \
- ->Args({ GradientGetValues::GetValuePermutation::SAMPLER_GET_VALUES, 4096 }) \
- ->ArgNames({ "SamplerGetValues", "size" }) \
- ->Unit(::benchmark::kMillisecond);
-
// --------------------------------------------------------------------------------------
// Base Gradients
BENCHMARK_DEFINE_F(GradientGetValues, BM_ConstantGradient)(benchmark::State& state)
{
auto entity = BuildTestConstantGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_ImageGradient)(benchmark::State& state)
{
auto entity = BuildTestImageGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_PerlinGradient)(benchmark::State& state)
{
auto entity = BuildTestPerlinGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_RandomGradient)(benchmark::State& state)
{
auto entity = BuildTestRandomGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_ShapeAreaFalloffGradient)(benchmark::State& state)
{
auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_ConstantGradient);
@@ -250,21 +73,21 @@ namespace UnitTest
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_InvertGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_LevelsGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_MixedGradient)(benchmark::State& state)
@@ -272,35 +95,35 @@ namespace UnitTest
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds);
auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_PosterizeGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_ReferenceGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_SmoothStepGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_ThresholdGradient)(benchmark::State& state)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId());
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_DitherGradient);
@@ -321,7 +144,7 @@ namespace UnitTest
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceMaskGradient)(benchmark::State& state)
@@ -330,7 +153,7 @@ namespace UnitTest
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
BENCHMARK_DEFINE_F(GradientGetValues, BM_SurfaceSlopeGradient)(benchmark::State& state)
@@ -339,7 +162,7 @@ namespace UnitTest
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds);
- RunGetValueOrGetValuesBenchmark(state, entity->GetId());
+ GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(state, entity->GetId());
}
GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(GradientGetValues, BM_SurfaceAltitudeGradient);
diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp
index 6c4ebcc4c0..f0ad53ee64 100644
--- a/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp
+++ b/Gems/GradientSignal/Code/Tests/GradientSignalGetValuesTests.cpp
@@ -8,6 +8,7 @@
#include
+#include
#include
namespace UnitTest
@@ -18,79 +19,36 @@ namespace UnitTest
// Create an arbitrary size shape for comparing values within. It should be large enough that we detect any value anomalies
// but small enough that the tests run quickly.
const float TestShapeHalfBounds = 128.0f;
-
- void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId)
- {
- // Create a gradient sampler and run through a series of points to see if they match expectations.
-
- const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds));
- const AZ::Vector2 stepSize(1.0f, 1.0f);
-
- GradientSignal::GradientSampler gradientSampler;
- gradientSampler.m_gradientId = gradientEntityId;
-
- const size_t numSamplesX = aznumeric_cast(ceil(queryRegion.GetExtents().GetX() / stepSize.GetX()));
- const size_t numSamplesY = aznumeric_cast(ceil(queryRegion.GetExtents().GetY() / stepSize.GetY()));
-
- // Build up the list of positions to query.
- AZStd::vector positions(numSamplesX * numSamplesY);
- size_t index = 0;
- for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++)
- {
- float y = queryRegion.GetMin().GetY() + (stepSize.GetY() * yIndex);
- for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++)
- {
- float x = queryRegion.GetMin().GetX() + (stepSize.GetX() * xIndex);
- positions[index++] = AZ::Vector3(x, y, 0.0f);
- }
- }
-
- // Get the results from GetValues
- AZStd::vector results(numSamplesX * numSamplesY);
- gradientSampler.GetValues(positions, results);
-
- // For each position, call GetValue and verify that the values match.
- for (size_t positionIndex = 0; positionIndex < positions.size(); positionIndex++)
- {
- GradientSignal::GradientSampleParams params;
- params.m_position = positions[positionIndex];
- float value = gradientSampler.GetValue(params);
-
- // We use ASSERT_NEAR instead of EXPECT_NEAR because if one value doesn't match, they probably all won't, so there's no
- // reason to keep running and printing failures for every value.
- ASSERT_NEAR(value, results[positionIndex], 0.000001f);
- }
- }
};
TEST_F(GradientSignalGetValuesTestsFixture, ImageGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestImageGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, PerlinGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestPerlinGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, RandomGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestRandomGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, ConstantGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestConstantGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, ShapeAreaFalloffGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto entity = BuildTestShapeAreaFalloffGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, DitherGradientComponent_VerifyGetValueAndGetValuesMatch)
@@ -98,21 +56,21 @@ namespace UnitTest
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestDitherGradient(TestShapeHalfBounds, baseEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, InvertGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestInvertGradient(TestShapeHalfBounds, baseEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, LevelsGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestLevelsGradient(TestShapeHalfBounds, baseEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, MixedGradientComponent_VerifyGetValueAndGetValuesMatch)
@@ -120,35 +78,35 @@ namespace UnitTest
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto mixedEntity = BuildTestConstantGradient(TestShapeHalfBounds);
auto entity = BuildTestMixedGradient(TestShapeHalfBounds, baseEntity->GetId(), mixedEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, PosterizeGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestPosterizeGradient(TestShapeHalfBounds, baseEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, ReferenceGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestReferenceGradient(TestShapeHalfBounds, baseEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, SmoothStepGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestSmoothStepGradient(TestShapeHalfBounds, baseEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, ThresholdGradientComponent_VerifyGetValueAndGetValuesMatch)
{
auto baseEntity = BuildTestRandomGradient(TestShapeHalfBounds);
auto entity = BuildTestThresholdGradient(TestShapeHalfBounds, baseEntity->GetId());
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceAltitudeGradientComponent_VerifyGetValueAndGetValuesMatch)
@@ -157,7 +115,7 @@ namespace UnitTest
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceAltitudeGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceMaskGradientComponent_VerifyGetValueAndGetValuesMatch)
@@ -166,7 +124,7 @@ namespace UnitTest
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceMaskGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
TEST_F(GradientSignalGetValuesTestsFixture, SurfaceSlopeGradientComponent_VerifyGetValueAndGetValuesMatch)
@@ -175,7 +133,7 @@ namespace UnitTest
CreateMockSurfaceDataSystem(AZ::Aabb::CreateFromMinMax(AZ::Vector3(-TestShapeHalfBounds), AZ::Vector3(TestShapeHalfBounds)));
auto entity = BuildTestSurfaceSlopeGradient(TestShapeHalfBounds);
- CompareGetValueAndGetValues(entity->GetId());
+ GradientSignalTestHelpers::CompareGetValueAndGetValues(entity->GetId(), TestShapeHalfBounds);
}
}
diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp
new file mode 100644
index 0000000000..46cc3475e8
--- /dev/null
+++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+
+#include
+#include
+#include
+
+namespace UnitTest
+{
+ void GradientSignalTestHelpers::CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds)
+ {
+ // Create a gradient sampler and run through a series of points to see if they match expectations.
+
+ const AZ::Aabb queryRegion = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-shapeHalfBounds), AZ::Vector3(shapeHalfBounds));
+ const AZ::Vector2 stepSize(1.0f, 1.0f);
+
+ GradientSignal::GradientSampler gradientSampler;
+ gradientSampler.m_gradientId = gradientEntityId;
+
+ const size_t numSamplesX = aznumeric_cast(ceil(queryRegion.GetExtents().GetX() / stepSize.GetX()));
+ const size_t numSamplesY = aznumeric_cast(ceil(queryRegion.GetExtents().GetY() / stepSize.GetY()));
+
+ // Build up the list of positions to query.
+ AZStd::vector positions(numSamplesX * numSamplesY);
+ size_t index = 0;
+ for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++)
+ {
+ float y = queryRegion.GetMin().GetY() + (stepSize.GetY() * yIndex);
+ for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++)
+ {
+ float x = queryRegion.GetMin().GetX() + (stepSize.GetX() * xIndex);
+ positions[index++] = AZ::Vector3(x, y, 0.0f);
+ }
+ }
+
+ // Get the results from GetValues
+ AZStd::vector results(numSamplesX * numSamplesY);
+ gradientSampler.GetValues(positions, results);
+
+ // For each position, call GetValue and verify that the values match.
+ for (size_t positionIndex = 0; positionIndex < positions.size(); positionIndex++)
+ {
+ GradientSignal::GradientSampleParams params;
+ params.m_position = positions[positionIndex];
+ float value = gradientSampler.GetValue(params);
+
+ // We use ASSERT_NEAR instead of EXPECT_NEAR because if one value doesn't match, they probably all won't, so there's no
+ // reason to keep running and printing failures for every value.
+ ASSERT_NEAR(value, results[positionIndex], 0.000001f);
+ }
+ }
+
+#ifdef HAVE_BENCHMARK
+
+ void GradientSignalTestHelpers::FillQueryPositions(AZStd::vector& positions, float height, float width)
+ {
+ size_t index = 0;
+ for (float y = 0.0f; y < height; y += 1.0f)
+ {
+ for (float x = 0.0f; x < width; x += 1.0f)
+ {
+ positions[index++] = AZ::Vector3(x, y, 0.0f);
+ }
+ }
+ }
+
+ void GradientSignalTestHelpers::RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
+ {
+ AZ_PROFILE_FUNCTION(Entity);
+
+ GradientSignal::GradientSampleParams params;
+
+ // Get the height and width ranges for querying from our benchmark parameters
+ const float height = aznumeric_cast(queryRange);
+ const float width = aznumeric_cast(queryRange);
+
+ // Call GetValue() on the EBus for every height and width in our ranges.
+ for (auto _ : state)
+ {
+ for (float y = 0.0f; y < height; y += 1.0f)
+ {
+ for (float x = 0.0f; x < width; x += 1.0f)
+ {
+ float value = 0.0f;
+ params.m_position = AZ::Vector3(x, y, 0.0f);
+ GradientSignal::GradientRequestBus::EventResult(
+ value, gradientId, &GradientSignal::GradientRequestBus::Events::GetValue, params);
+ benchmark::DoNotOptimize(value);
+ }
+ }
+ }
+ }
+
+ void GradientSignalTestHelpers::RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
+ {
+ AZ_PROFILE_FUNCTION(Entity);
+
+ // Get the height and width ranges for querying from our benchmark parameters
+ float height = aznumeric_cast(queryRange);
+ float width = aznumeric_cast(queryRange);
+ int64_t totalQueryPoints = queryRange * queryRange;
+
+ // Call GetValues() for every height and width in our ranges.
+ for (auto _ : state)
+ {
+ // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create
+ // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable.
+ AZStd::vector positions(totalQueryPoints);
+ FillQueryPositions(positions, height, width);
+
+ // Query and get the results.
+ AZStd::vector results(totalQueryPoints);
+ GradientSignal::GradientRequestBus::Event(
+ gradientId, &GradientSignal::GradientRequestBus::Events::GetValues, positions, results);
+ }
+ }
+
+ void GradientSignalTestHelpers::RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
+ {
+ AZ_PROFILE_FUNCTION(Entity);
+
+ // Create a gradient sampler to use for querying our gradient.
+ GradientSignal::GradientSampler gradientSampler;
+ gradientSampler.m_gradientId = gradientId;
+
+ // Get the height and width ranges for querying from our benchmark parameters
+ const float height = aznumeric_cast(queryRange);
+ const float width = aznumeric_cast(queryRange);
+
+ // Call GetValue() through the GradientSampler for every height and width in our ranges.
+ for (auto _ : state)
+ {
+ for (float y = 0.0f; y < height; y += 1.0f)
+ {
+ for (float x = 0.0f; x < width; x += 1.0f)
+ {
+ GradientSignal::GradientSampleParams params;
+ params.m_position = AZ::Vector3(x, y, 0.0f);
+ float value = gradientSampler.GetValue(params);
+ benchmark::DoNotOptimize(value);
+ }
+ }
+ }
+ }
+
+ void GradientSignalTestHelpers::RunSamplerGetValuesBenchmark(
+ benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange)
+ {
+ AZ_PROFILE_FUNCTION(Entity);
+
+ // Create a gradient sampler to use for querying our gradient.
+ GradientSignal::GradientSampler gradientSampler;
+ gradientSampler.m_gradientId = gradientId;
+
+ // Get the height and width ranges for querying from our benchmark parameters
+ const float height = aznumeric_cast(queryRange);
+ const float width = aznumeric_cast(queryRange);
+ const int64_t totalQueryPoints = queryRange * queryRange;
+
+ // Call GetValues() through the GradientSampler for every height and width in our ranges.
+ for (auto _ : state)
+ {
+ // Set up our vector of query positions. This is done inside the benchmark timing since we're counting the work to create
+ // each query position in the single GetValue() call benchmarks, and will make the timing more directly comparable.
+ AZStd::vector positions(totalQueryPoints);
+ FillQueryPositions(positions, height, width);
+
+ // Query and get the results.
+ AZStd::vector results(totalQueryPoints);
+ gradientSampler.GetValues(positions, results);
+ }
+ }
+
+ void GradientSignalTestHelpers::RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId)
+ {
+ switch (state.range(0))
+ {
+ case GetValuePermutation::EBUS_GET_VALUE:
+ RunEBusGetValueBenchmark(state, gradientId, state.range(1));
+ break;
+ case GetValuePermutation::EBUS_GET_VALUES:
+ RunEBusGetValuesBenchmark(state, gradientId, state.range(1));
+ break;
+ case GetValuePermutation::SAMPLER_GET_VALUE:
+ RunSamplerGetValueBenchmark(state, gradientId, state.range(1));
+ break;
+ case GetValuePermutation::SAMPLER_GET_VALUES:
+ RunSamplerGetValuesBenchmark(state, gradientId, state.range(1));
+ break;
+ default:
+ AZ_Assert(false, "Benchmark permutation type not supported.");
+ }
+ }
+#endif
+}
+
+
diff --git a/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h
new file mode 100644
index 0000000000..8a175939ee
--- /dev/null
+++ b/Gems/GradientSignal/Code/Tests/GradientSignalTestHelpers.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace UnitTest
+{
+ class GradientSignalTestHelpers
+ {
+ public:
+ static void CompareGetValueAndGetValues(AZ::EntityId gradientEntityId, float shapeHalfBounds);
+
+#ifdef HAVE_BENCHMARK
+ // We use an enum to list out the different types of GetValue() benchmarks to run so that way we can condense our test cases
+ // to just take the value in as a benchmark argument and switch on it. Otherwise, we would need to write a different benchmark
+ // function for each test case for each gradient.
+ enum GetValuePermutation : int64_t
+ {
+ EBUS_GET_VALUE,
+ EBUS_GET_VALUES,
+ SAMPLER_GET_VALUE,
+ SAMPLER_GET_VALUES,
+ };
+
+ static void FillQueryPositions(AZStd::vector& positions, float height, float width);
+
+ static void RunEBusGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
+ static void RunEBusGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
+ static void RunSamplerGetValueBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
+ static void RunSamplerGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId, int64_t queryRange);
+ static void RunGetValueOrGetValuesBenchmark(benchmark::State& state, const AZ::EntityId& gradientId);
+
+// Because there's no good way to label different enums in the output results (they just appear as integer values), we work around it by
+// registering one set of benchmark runs for each enum value and use ArgNames() to give it a friendly name in the results.
+#ifndef GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F
+#define GRADIENT_SIGNAL_GET_VALUES_BENCHMARK_REGISTER_F(Fixture, Func) \
+ BENCHMARK_REGISTER_F(Fixture, Func) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 1024 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 2048 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUE, 4096 }) \
+ ->ArgNames({ "EbusGetValue", "size" }) \
+ ->Unit(::benchmark::kMillisecond); \
+ BENCHMARK_REGISTER_F(Fixture, Func) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 1024 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 2048 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::EBUS_GET_VALUES, 4096 }) \
+ ->ArgNames({ "EbusGetValues", "size" }) \
+ ->Unit(::benchmark::kMillisecond); \
+ BENCHMARK_REGISTER_F(Fixture, Func) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 1024 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 2048 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUE, 4096 }) \
+ ->ArgNames({ "SamplerGetValue", "size" }) \
+ ->Unit(::benchmark::kMillisecond); \
+ BENCHMARK_REGISTER_F(Fixture, Func) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 1024 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 2048 }) \
+ ->Args({ GradientSignalTestHelpers::GetValuePermutation::SAMPLER_GET_VALUES, 4096 }) \
+ ->ArgNames({ "SamplerGetValues", "size" }) \
+ ->Unit(::benchmark::kMillisecond);
+#endif
+
+#endif
+ };
+
+
+}
diff --git a/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake b/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake
index 7d867b0a33..98ab57b7b0 100644
--- a/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake
+++ b/Gems/GradientSignal/Code/gradientsignal_shared_tests_files.cmake
@@ -7,6 +7,8 @@
#
set(FILES
+ Tests/GradientSignalTestHelpers.cpp
+ Tests/GradientSignalTestHelpers.h
Tests/GradientSignalTestFixtures.cpp
Tests/GradientSignalTestFixtures.h
Tests/GradientSignalTestMocks.cpp