d0e5f9d20b
* Added Async APIs for the various Process*FromList terrain functions. Please note that we are currently defaulting the number of worker threads to one, because splitting the work over multiple threads causes contention when locking various mutexes, resulting in slower overall wall time for async requests split over multiple threads vs one where all the work is done on a single thread. The latter is still preferable over a regular synchronous call because it is just as quick and prevents the main thread from blocking. This should be changed once the mutex contention issues have been addressed, so that async calls automatically split the work between available job manager worker threads, unless the ProcessAsyncParams specify a different desired number of jobs. Signed-off-by: bosnichd <bosnichd@amazon.com> * Fix Linux builds by adding missing #include Signed-off-by: bosnichd <bosnichd@amazon.com> * Added a test for cancellation of terrain async requests, and fix it so that it works. Note that the benchmarks show this implementation to be slightly slower than the previous one, which I presume is because we're now calling a 'perSurfacePointFunction' in the inner loop; this can probably be addressed, but will result in a lot of code duplication, and I think efforts will be better spent on removing the mutex contention to enable running multiple terrain async jobs at the same time. Signed-off-by: bosnichd <bosnichd@amazon.com> * Added Async versions for all Process*Region terrain API functions, along with benchmarks. Signed-off-by: bosnichd <bosnichd@amazon.com> * Fix the newly added terrain async request benchmarks to actually use the async APIs. Signed-off-by: bosnichd <bosnichd@amazon.com> * Revert to the original version which just calls the synchronous API from the job function, along with some other updates in response to review feedback. Signed-off-by: bosnichd <bosnichd@amazon.com> * Change the TerrainWorldDebugger to use the async API, along with the following changes: - TerrainJobContext no longer uses a JobCancelGroup so we can guarantee the completion callbacks of associated jobs will be invoked even if it is cancelled. - As a result of the above change, the ProcessAsyncCompleteCallback function signature again accepts the associated TerrainJobContext as a param. - The TerrainProcessAsyncCancellation test has been resurrected and simplified by using binary semaphores instead of condition variables. - All the async related TerrainSystemBenchmark functions have been simplified by using binary semaphores instead of condition variables. - Global cancellation of all terrain jobs on deactivation of the TerrainSystem has been reintroduced, but in a different way than before. - Other miscellaneous changes/fixes made while testing and based on earlier PR feedback. Signed-off-by: bosnichd <bosnichd@amazon.com> * Updates based on review feedback: - Go back to using a vector instead of an array (fixed the original problem by adding custom copy/assignment constructors/operators to the WireframeSector struct). - When calling WireframeSector::Reset, block until any associated in flight has completed. - Added the concept of a minimum number of positions per terrain job. Signed-off-by: bosnichd <bosnichd@amazon.com> * Use semaphore instead of binary_semaphore in a bunch of places to account for the race condition where a completion callback fires before we started waiting for it. Signed-off-by: bosnichd <bosnichd@amazon.com>
1126 lines
62 KiB
C++
1126 lines
62 KiB
C++
/*
|
|
* 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 <AzCore/Component/ComponentApplication.h>
|
|
#include <AzCore/Component/Entity.h>
|
|
#include <AzCore/Component/TransformBus.h>
|
|
#include <AzCore/Math/Random.h>
|
|
#include <AzCore/Memory/PoolAllocator.h>
|
|
#include <AzCore/Jobs/JobManagerComponent.h>
|
|
#include <AzCore/std/parallel/semaphore.h>
|
|
#include <AzCore/UnitTest/TestTypes.h>
|
|
#include <AzFramework/Components/TransformComponent.h>
|
|
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
|
|
#include <AzTest/AzTest.h>
|
|
|
|
#include <GradientSignal/Components/RandomGradientComponent.h>
|
|
#include <GradientSignal/Components/GradientTransformComponent.h>
|
|
#include <GradientSignal/Ebuses/GradientRequestBus.h>
|
|
|
|
#include <SurfaceData/SurfaceDataTypes.h>
|
|
|
|
#include <LmbrCentral/Shape/ShapeComponentBus.h>
|
|
#include <MockAxisAlignedBoxShapeComponent.h>
|
|
|
|
#include <TerrainSystem/TerrainSystem.h>
|
|
#include <Components/TerrainLayerSpawnerComponent.h>
|
|
#include <Components/TerrainHeightGradientListComponent.h>
|
|
#include <Components/TerrainSurfaceGradientListComponent.h>
|
|
|
|
#include <benchmark/benchmark.h>
|
|
|
|
namespace UnitTest
|
|
{
|
|
using ::testing::NiceMock;
|
|
using ::testing::Return;
|
|
|
|
class TerrainSystemBenchmarkFixture
|
|
: public UnitTest::AllocatorsBenchmarkFixture
|
|
, public UnitTest::TraceBusRedirector
|
|
{
|
|
public:
|
|
void SetUp(const benchmark::State& state) override
|
|
{
|
|
InternalSetUp(state);
|
|
}
|
|
void SetUp(benchmark::State& state) override
|
|
{
|
|
InternalSetUp(state);
|
|
}
|
|
|
|
void TearDown(const benchmark::State& state) override
|
|
{
|
|
InternalTearDown(state);
|
|
}
|
|
void TearDown(benchmark::State& state) override
|
|
{
|
|
InternalTearDown(state);
|
|
}
|
|
|
|
void InternalSetUp(const benchmark::State& state)
|
|
{
|
|
AZ::Debug::TraceMessageBus::Handler::BusConnect();
|
|
UnitTest::AllocatorsBenchmarkFixture::SetUp(state);
|
|
|
|
m_app = AZStd::make_unique<AZ::ComponentApplication>();
|
|
ASSERT_TRUE(m_app != nullptr);
|
|
|
|
AZ::ComponentApplication::Descriptor componentAppDesc;
|
|
|
|
AZ::Entity* systemEntity = m_app->Create(componentAppDesc);
|
|
ASSERT_TRUE(systemEntity != nullptr);
|
|
m_app->AddEntity(systemEntity);
|
|
|
|
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
|
|
}
|
|
|
|
void InternalTearDown(const benchmark::State& state)
|
|
{
|
|
AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
|
|
|
|
m_app->Destroy();
|
|
m_app.reset();
|
|
|
|
UnitTest::AllocatorsBenchmarkFixture::TearDown(state);
|
|
AZ::Debug::TraceMessageBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
AZStd::unique_ptr<AZ::Entity> CreateEntity()
|
|
{
|
|
return AZStd::make_unique<AZ::Entity>();
|
|
}
|
|
|
|
void ActivateEntity(AZ::Entity* entity)
|
|
{
|
|
entity->Init();
|
|
entity->Activate();
|
|
}
|
|
|
|
template<typename Component, typename Configuration>
|
|
Component* CreateComponent(AZ::Entity* entity, const Configuration& config)
|
|
{
|
|
m_app->RegisterComponentDescriptor(Component::CreateDescriptor());
|
|
return entity->CreateComponent<Component>(config);
|
|
}
|
|
|
|
template<typename Component>
|
|
Component* CreateComponent(AZ::Entity* entity)
|
|
{
|
|
m_app->RegisterComponentDescriptor(Component::CreateDescriptor());
|
|
return entity->CreateComponent<Component>();
|
|
}
|
|
|
|
// Create a terrain system with reasonable defaults for testing, but with the ability to override the defaults
|
|
// on a test-by-test basis.
|
|
AZStd::unique_ptr<Terrain::TerrainSystem> CreateAndActivateTerrainSystem(
|
|
float queryResolution = 1.0f,
|
|
AZ::Aabb worldBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-128.0f), AZ::Vector3(128.0f)))
|
|
{
|
|
// Create the terrain system and give it one tick to fully initialize itself.
|
|
auto terrainSystem = AZStd::make_unique<Terrain::TerrainSystem>();
|
|
terrainSystem->SetTerrainAabb(worldBounds);
|
|
terrainSystem->SetTerrainHeightQueryResolution(queryResolution);
|
|
terrainSystem->Activate();
|
|
AZ::TickBus::Broadcast(&AZ::TickBus::Events::OnTick, 0.f, AZ::ScriptTimePoint{});
|
|
return terrainSystem;
|
|
}
|
|
|
|
// Create a mock shape bus listener that will listen to the given EntityId for shape requests and returns the following:
|
|
// - GetEncompassingAabb - returns the given Aabb
|
|
// - GetTransformAndLocalBounds - returns the center of the Aabb as the transform, and the size of the Aabb as the local bounds
|
|
// - IsPointInside - true if the point is in the Aabb, false if not
|
|
AZStd::unique_ptr<NiceMock<UnitTest::MockShapeComponentRequests>> CreateMockShape(
|
|
const AZ::Aabb& spawnerBox, const AZ::EntityId& shapeEntityId)
|
|
{
|
|
AZStd::unique_ptr<NiceMock<UnitTest::MockShapeComponentRequests>> mockShape =
|
|
AZStd::make_unique<NiceMock<UnitTest::MockShapeComponentRequests>>(shapeEntityId);
|
|
|
|
ON_CALL(*mockShape, GetEncompassingAabb).WillByDefault(Return(spawnerBox));
|
|
ON_CALL(*mockShape, GetTransformAndLocalBounds)
|
|
.WillByDefault(
|
|
[spawnerBox](AZ::Transform& transform, AZ::Aabb& bounds)
|
|
{
|
|
transform = AZ::Transform::CreateTranslation(spawnerBox.GetCenter());
|
|
bounds = spawnerBox.GetTranslated(-spawnerBox.GetCenter());
|
|
});
|
|
ON_CALL(*mockShape, IsPointInside)
|
|
.WillByDefault(
|
|
[spawnerBox](const AZ::Vector3& point) -> bool
|
|
{
|
|
return spawnerBox.Contains(point);
|
|
});
|
|
|
|
return mockShape;
|
|
}
|
|
|
|
// Create an entity with a Random Gradient on it that can be used for gradient queries.
|
|
AZStd::unique_ptr<AZ::Entity> CreateTestRandomGradientEntity(const AZ::Aabb& spawnerBox, uint32_t randomSeed)
|
|
{
|
|
// Create the base entity
|
|
AZStd::unique_ptr<AZ::Entity> testGradientEntity = CreateEntity();
|
|
|
|
// Add a mock AABB Shape so that the shape requirement is fulfilled.
|
|
CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>(testGradientEntity.get());
|
|
|
|
// Create the Random Gradient Component with some default parameters.
|
|
GradientSignal::RandomGradientConfig config;
|
|
config.m_randomSeed = randomSeed;
|
|
CreateComponent<GradientSignal::RandomGradientComponent>(testGradientEntity.get(), config);
|
|
|
|
// Create the Gradient Transform Component with some default parameters.
|
|
GradientSignal::GradientTransformConfig gradientTransformConfig;
|
|
gradientTransformConfig.m_wrappingType = GradientSignal::WrappingType::None;
|
|
CreateComponent<GradientSignal::GradientTransformComponent>(testGradientEntity.get(), gradientTransformConfig);
|
|
|
|
// Set the transform to match the given spawnerBox
|
|
auto transform = CreateComponent<AzFramework::TransformComponent>(testGradientEntity.get());
|
|
transform->SetLocalTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
|
transform->SetWorldTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
|
|
|
return testGradientEntity;
|
|
}
|
|
|
|
AZStd::unique_ptr<AZ::Entity> CreateTestLayerSpawnerEntity(
|
|
const AZ::Aabb& spawnerBox, const AZ::EntityId& heightGradientEntityId,
|
|
const Terrain::TerrainSurfaceGradientListConfig& surfaceConfig)
|
|
{
|
|
// Create the base entity
|
|
AZStd::unique_ptr<AZ::Entity> testLayerSpawnerEntity = CreateEntity();
|
|
|
|
// Add a mock AABB Shape so that the shape requirement is fulfilled.
|
|
CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>(testLayerSpawnerEntity.get());
|
|
|
|
// Add a Terrain Layer Spawner
|
|
CreateComponent<Terrain::TerrainLayerSpawnerComponent>(testLayerSpawnerEntity.get());
|
|
|
|
// Add a Terrain Height Gradient List with one entry pointing to the given gradient entity
|
|
Terrain::TerrainHeightGradientListConfig heightConfig;
|
|
heightConfig.m_gradientEntities.emplace_back(heightGradientEntityId);
|
|
CreateComponent<Terrain::TerrainHeightGradientListComponent>(testLayerSpawnerEntity.get(), heightConfig);
|
|
|
|
// Add a Terrain Surface Gradient List with however many entries we were given
|
|
CreateComponent<Terrain::TerrainSurfaceGradientListComponent>(testLayerSpawnerEntity.get(), surfaceConfig);
|
|
|
|
// Set the transform to match the given spawnerBox
|
|
auto transform = CreateComponent<AzFramework::TransformComponent>(testLayerSpawnerEntity.get());
|
|
transform->SetLocalTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
|
transform->SetWorldTM(AZ::Transform::CreateTranslation(spawnerBox.GetCenter()));
|
|
|
|
return testLayerSpawnerEntity;
|
|
}
|
|
|
|
void RunTerrainApiBenchmark(
|
|
benchmark::State& state,
|
|
AZStd::function<void(
|
|
float queryResolution,
|
|
const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)> ApiCaller)
|
|
{
|
|
// Get the ranges for querying from our benchmark parameters
|
|
float boundsRange = aznumeric_cast<float>(state.range(0));
|
|
uint32_t numSurfaces = aznumeric_cast<uint32_t>(state.range(1));
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler =
|
|
static_cast<AzFramework::Terrain::TerrainDataRequests::Sampler>(state.range(2));
|
|
|
|
// Set up our world bounds and query resolution
|
|
AZ::Aabb worldBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(-boundsRange / 2.0f), AZ::Vector3(boundsRange / 2.0f));
|
|
float queryResolution = 1.0f;
|
|
|
|
// Create a Random Gradient to use as our height provider
|
|
const uint32_t heightRandomSeed = 12345;
|
|
auto heightGradientEntity = CreateTestRandomGradientEntity(worldBounds, heightRandomSeed);
|
|
auto heightGradientShapeRequests = CreateMockShape(worldBounds, heightGradientEntity->GetId());
|
|
ActivateEntity(heightGradientEntity.get());
|
|
|
|
|
|
// Create a set of Random Gradients to use as our surface providers
|
|
Terrain::TerrainSurfaceGradientListConfig surfaceConfig;
|
|
AZStd::vector<AZStd::unique_ptr<AZ::Entity>> surfaceGradientEntities;
|
|
AZStd::vector<AZStd::unique_ptr<NiceMock<UnitTest::MockShapeComponentRequests>>> surfaceGradientShapeRequests;
|
|
for (uint32_t surfaces = 0; surfaces < numSurfaces; surfaces++)
|
|
{
|
|
const uint32_t surfaceRandomSeed = 23456 + surfaces;
|
|
auto surfaceGradientEntity = CreateTestRandomGradientEntity(worldBounds, surfaceRandomSeed);
|
|
auto shapeRequests = CreateMockShape(worldBounds, surfaceGradientEntity->GetId());
|
|
ActivateEntity(surfaceGradientEntity.get());
|
|
|
|
// Give each gradient a new surface tag
|
|
surfaceConfig.m_gradientSurfaceMappings.emplace_back(
|
|
surfaceGradientEntity->GetId(), SurfaceData::SurfaceTag(AZStd::string::format("test%u", surfaces)));
|
|
|
|
surfaceGradientEntities.emplace_back(AZStd::move(surfaceGradientEntity));
|
|
surfaceGradientShapeRequests.emplace_back(AZStd::move(shapeRequests));
|
|
}
|
|
|
|
// Create a single Terrain Layer Spawner that covers the entire terrain world bounds
|
|
// (Do this *after* creating and activating the height and surface gradients)
|
|
auto testLayerSpawnerEntity = CreateTestLayerSpawnerEntity(worldBounds, heightGradientEntity->GetId(), surfaceConfig);
|
|
auto spawnerShapeRequests = CreateMockShape(worldBounds, testLayerSpawnerEntity->GetId());
|
|
ActivateEntity(testLayerSpawnerEntity.get());
|
|
|
|
// Create the global job manager.
|
|
auto serializeContext = AZStd::make_unique<AZ::SerializeContext>();
|
|
auto jobManagerComponentDescriptor = AZ::JobManagerComponent::CreateDescriptor();
|
|
jobManagerComponentDescriptor->Reflect(serializeContext.get());
|
|
auto jobManagerEntity = AZStd::make_unique<AZ::Entity>();
|
|
jobManagerEntity->CreateComponent<AZ::JobManagerComponent>();
|
|
jobManagerEntity->Init();
|
|
jobManagerEntity->Activate();
|
|
|
|
// Create the terrain system (do this after creating the terrain layer entity to ensure that we don't need any data refreshes)
|
|
// Also ensure to do this after creating the global JobManager.
|
|
auto terrainSystem = CreateAndActivateTerrainSystem(queryResolution, worldBounds);
|
|
|
|
// Call the terrain API we're testing for every height and width in our ranges.
|
|
for (auto stateIterator : state)
|
|
{
|
|
ApiCaller(queryResolution, worldBounds, sampler);
|
|
}
|
|
|
|
testLayerSpawnerEntity.reset();
|
|
spawnerShapeRequests.reset();
|
|
|
|
heightGradientEntity.reset();
|
|
heightGradientShapeRequests.reset();
|
|
|
|
surfaceGradientEntities.clear();
|
|
surfaceGradientShapeRequests.clear();
|
|
}
|
|
|
|
void GenerateInputPositionsList(float queryResolution, const AZ::Aabb& worldBounds, AZStd::vector<AZ::Vector3>& positions)
|
|
{
|
|
const size_t numSamplesX = aznumeric_cast<size_t>(ceil(worldBounds.GetExtents().GetX() / queryResolution));
|
|
const size_t numSamplesY = aznumeric_cast<size_t>(ceil(worldBounds.GetExtents().GetY() / queryResolution));
|
|
|
|
for (size_t y = 0; y < numSamplesY; y++)
|
|
{
|
|
float fy = aznumeric_cast<float>(worldBounds.GetMin().GetY() + (y * queryResolution));
|
|
for (size_t x = 0; x < numSamplesX; x++)
|
|
{
|
|
float fx = aznumeric_cast<float>(worldBounds.GetMin().GetX() + (x * queryResolution));
|
|
positions.emplace_back(fx, fy, 0.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected:
|
|
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
|
|
};
|
|
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetHeight)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
float worldMinZ = worldBounds.GetMin().GetZ();
|
|
|
|
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
|
{
|
|
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
|
{
|
|
float terrainHeight = worldMinZ;
|
|
bool terrainExists = false;
|
|
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
|
terrainHeight, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, sampler, &terrainExists);
|
|
benchmark::DoNotOptimize(terrainHeight);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetHeight)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsRegion)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_position.GetZ());
|
|
};
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegion, worldBounds, stepSize, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsRegion)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsRegionAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_position.GetZ());
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromRegionAsync, worldBounds, stepSize, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsRegionAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsList)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_position.GetZ());
|
|
};
|
|
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromList, inPositions, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsList)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsListAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_position.GetZ());
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessHeightsFromListAsync, inPositions, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessHeightsListAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetNormal)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
|
{
|
|
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
|
{
|
|
AZ::Vector3 terrainNormal;
|
|
bool terrainExists = false;
|
|
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
|
terrainNormal, &AzFramework::Terrain::TerrainDataRequests::GetNormalFromFloats, x, y, sampler, &terrainExists);
|
|
benchmark::DoNotOptimize(terrainNormal);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetNormal)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsRegion)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_normal);
|
|
};
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessNormalsFromRegion, worldBounds, stepSize, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsRegion)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsRegionAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_normal);
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessNormalsFromRegionAsync, worldBounds, stepSize, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsRegionAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsList)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_normal);
|
|
};
|
|
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessNormalsFromList, inPositions, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsList)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsListAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_normal);
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessNormalsFromListAsync, inPositions, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessNormalsListAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetSurfaceWeights)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AzFramework::SurfaceData::SurfaceTagWeightList surfaceWeights;
|
|
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
|
{
|
|
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
|
{
|
|
bool terrainExists = false;
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::GetSurfaceWeightsFromFloats, x, y, surfaceWeights, sampler,
|
|
&terrainExists);
|
|
benchmark::DoNotOptimize(surfaceWeights);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetSurfaceWeights)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsRegion)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_surfaceTags);
|
|
};
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfaceWeightsFromRegion, worldBounds, stepSize, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsRegion)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsRegionAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_surfaceTags);
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfaceWeightsFromRegionAsync, worldBounds, stepSize, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsRegionAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsList)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_surfaceTags);
|
|
};
|
|
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfaceWeightsFromList, inPositions, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsList)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsListAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint.m_surfaceTags);
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfaceWeightsFromListAsync, inPositions, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfaceWeightsListAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 2, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 4, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetSurfacePoints)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AzFramework::SurfaceData::SurfacePoint surfacePoint;
|
|
for (float y = worldBounds.GetMin().GetY(); y < worldBounds.GetMax().GetY(); y += 1.0f)
|
|
{
|
|
for (float x = worldBounds.GetMin().GetX(); x < worldBounds.GetMax().GetX(); x += 1.0f)
|
|
{
|
|
bool terrainExists = false;
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::GetSurfacePointFromFloats, x, y, surfacePoint, sampler,
|
|
&terrainExists);
|
|
benchmark::DoNotOptimize(surfacePoint);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetSurfacePoints)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsRegion)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint);
|
|
};
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromRegion, worldBounds, stepSize, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsRegion)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsRegionAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
auto perPositionCallback = []([[maybe_unused]] size_t xIndex, [[maybe_unused]] size_t yIndex,
|
|
const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint);
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
|
|
AZ::Vector2 stepSize = AZ::Vector2(queryResolution);
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromRegionAsync, worldBounds, stepSize, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsRegionAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsList)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint);
|
|
};
|
|
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromList, inPositions, perPositionCallback, sampler);
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsList)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsListAsync)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[this]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
AZStd::vector<AZ::Vector3> inPositions;
|
|
GenerateInputPositionsList(queryResolution, worldBounds, inPositions);
|
|
|
|
auto perPositionCallback = [](const AzFramework::SurfaceData::SurfacePoint& surfacePoint, [[maybe_unused]] bool terrainExists)
|
|
{
|
|
benchmark::DoNotOptimize(surfacePoint);
|
|
};
|
|
|
|
AZStd::semaphore completionEvent;
|
|
auto completionCallback = [&completionEvent](AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::TerrainJobContext>)
|
|
{
|
|
completionEvent.release();
|
|
};
|
|
|
|
AZStd::shared_ptr<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams> asyncParams
|
|
= AZStd::make_shared<AzFramework::Terrain::TerrainDataRequests::ProcessAsyncParams>();
|
|
asyncParams->m_completionCallback = completionCallback;
|
|
AzFramework::Terrain::TerrainDataRequestBus::Broadcast(
|
|
&AzFramework::Terrain::TerrainDataRequests::ProcessSurfacePointsFromListAsync, inPositions, perPositionCallback, sampler, asyncParams);
|
|
|
|
completionEvent.acquire();
|
|
}
|
|
);
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_ProcessSurfacePointsListAsync)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::BILINEAR) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::CLAMP) })
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetClosestIntersectionRandom)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
const uint32_t numRays = aznumeric_cast<uint32_t>(state.range(1));
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[numRays]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
[[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
// Cast rays starting at random positions above the terrain,
|
|
// and ending at a random positions below the terrain.
|
|
AZ::SimpleLcgRandom random;
|
|
AzFramework::RenderGeometry::RayRequest ray;
|
|
AzFramework::RenderGeometry::RayResult result;
|
|
for (uint32_t i = 0; i < numRays; ++i)
|
|
{
|
|
ray.m_startWorldPosition.SetX(worldBounds.GetMin().GetX() + (random.GetRandomFloat() * worldBounds.GetXExtent()));
|
|
ray.m_startWorldPosition.SetY(worldBounds.GetMin().GetY() + (random.GetRandomFloat() * worldBounds.GetYExtent()));
|
|
ray.m_startWorldPosition.SetZ(worldBounds.GetMax().GetZ());
|
|
ray.m_endWorldPosition.SetX(worldBounds.GetMin().GetX() + (random.GetRandomFloat() * worldBounds.GetXExtent()));
|
|
ray.m_endWorldPosition.SetY(worldBounds.GetMin().GetY() + (random.GetRandomFloat() * worldBounds.GetYExtent()));
|
|
ray.m_endWorldPosition.SetZ(worldBounds.GetMin().GetZ());
|
|
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
|
result, &AzFramework::Terrain::TerrainDataRequests::GetClosestIntersection, ray);
|
|
}
|
|
});
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetClosestIntersectionRandom)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 10, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 10, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 10, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 100, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 100, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 100, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 1000, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1000, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1000, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
|
|
BENCHMARK_DEFINE_F(TerrainSystemBenchmarkFixture, BM_GetClosestIntersectionWorstCase)(benchmark::State& state)
|
|
{
|
|
// Run the benchmark
|
|
const uint32_t numRays = aznumeric_cast<uint32_t>(state.range(1));
|
|
RunTerrainApiBenchmark(
|
|
state,
|
|
[numRays]([[maybe_unused]] float queryResolution, const AZ::Aabb& worldBounds,
|
|
[[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampler)
|
|
{
|
|
// Cast rays starting at an upper corner of the terrain world,
|
|
// and ending at the opposite top corner of the terrain world,
|
|
// traversing the entire grid without finding an intersection.
|
|
AzFramework::RenderGeometry::RayRequest ray;
|
|
AzFramework::RenderGeometry::RayResult result;
|
|
ray.m_startWorldPosition = worldBounds.GetMax();
|
|
ray.m_endWorldPosition = worldBounds.GetMin();
|
|
ray.m_endWorldPosition.SetZ(ray.m_startWorldPosition.GetZ());
|
|
for (uint32_t i = 0; i < numRays; ++i)
|
|
{
|
|
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
|
result, &AzFramework::Terrain::TerrainDataRequests::GetClosestIntersection, ray);
|
|
}
|
|
});
|
|
}
|
|
|
|
BENCHMARK_REGISTER_F(TerrainSystemBenchmarkFixture, BM_GetClosestIntersectionWorstCase)
|
|
->Args({ 1024, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 10, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 10, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 10, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 100, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 100, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 100, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 1024, 1000, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 2048, 1000, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Args({ 4096, 1000, static_cast<int>(AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT) })
|
|
->Unit(::benchmark::kMillisecond);
|
|
#endif
|
|
|
|
}
|