Skip to content

Commit

Permalink
Updated scene to do more multi threading
Browse files Browse the repository at this point in the history
  • Loading branch information
tippesi committed Jan 4, 2025
1 parent 4fd12f7 commit bb887b9
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 111 deletions.
12 changes: 4 additions & 8 deletions src/demo/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,7 @@ void App::Update(float deltaTime) {

}

scene->Timestep(deltaTime);
scene->Update();
scene->Update(deltaTime);

CheckLoadScene();

Expand Down Expand Up @@ -913,8 +912,7 @@ bool App::LoadScene() {
}
else if (sceneSelection == FOREST) {
auto otherScene = Atlas::Loader::ModelImporter::ImportScene("forest/forest.gltf", -glm::vec3(2048.0f), glm::vec3(2048.0f), 5, false, false, false, 2048);
otherScene->Timestep(1.0f);
otherScene->Update();
otherScene->Update(1.0f);

CopyActors(otherScene);

Expand All @@ -931,8 +929,7 @@ bool App::LoadScene() {
}
else if (sceneSelection == EMERALDSQUARE) {
auto otherScene = Atlas::Loader::ModelImporter::ImportScene("emeraldsquare/square.gltf", -glm::vec3(2048.0f), glm::vec3(2048.0f), 5, false, false, false, 2048);
otherScene->Timestep(1.0f);
otherScene->Update();
otherScene->Update(1.0f);

CopyActors(otherScene);

Expand Down Expand Up @@ -1045,8 +1042,7 @@ bool App::LoadScene() {
}
}

scene->Timestep(1.0f);
scene->Update();
scene->Update(1.0f);

Atlas::Clock::ResetAverage();

Expand Down
3 changes: 1 addition & 2 deletions src/editor/DataCreator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ namespace Atlas::Editor {
scene->rayTracingWorld = CreateRef<RayTracing::RayTracingWorld>();
scene->postProcessing.fsr2 = true;

scene->Timestep(1.0f);
scene->Update();
scene->Update(1.0f);

min = glm::vec3(std::numeric_limits<float>::max());
max = glm::vec3(-std::numeric_limits<float>::max());
Expand Down
4 changes: 2 additions & 2 deletions src/editor/ui/panels/SceneHierarchyPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ namespace Atlas::Editor::UI {
}

if (ImGui::BeginDragDropSource()) {
ImGui::SetDragDropPayload(typeid(Scene::Entity).name(), nullptr, 0);
ImGui::Text("Drag to other entity in hierarchy");
ImGui::SetDragDropPayload(typeid(Scene::Entity).name(), &entity, sizeof(Scene::Entity));
ImGui::Text("Drag to other entity in hierarchy or into content browser to create a prefab");

ImGui::EndDragDropSource();
}
Expand Down
6 changes: 2 additions & 4 deletions src/editor/ui/windows/SceneWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ namespace Atlas::Editor::UI {

// If we're playing we can update here since we don't expect values to change from the UI side
if (isPlaying) {
scene->Timestep(deltaTime);
scene->Update();
scene->Update(deltaTime);
}
else {
auto& camera = cameraEntity.GetComponent<CameraComponent>();
Expand Down Expand Up @@ -184,8 +183,7 @@ namespace Atlas::Editor::UI {
// Path tracing needs history while ray tracing
scene->rayTracingWorld->includeObjectHistory = Singletons::config->pathTrace;

scene->Timestep(Clock::GetDelta());
scene->Update();
scene->Update(Clock::GetDelta());

// Restore all previous camera main values
for (auto entity : cameraSubset) {
Expand Down
2 changes: 0 additions & 2 deletions src/engine/raytracing/RayTracingWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,6 @@ namespace Atlas {

UpdateMaterials();

JobSystem::Wait(renderState->mainCameraSignal, JobPriority::High);

vec3 cameraLocation;
auto hasCamera = scene->HasMainCamera();
if (hasCamera) {
Expand Down
155 changes: 73 additions & 82 deletions src/engine/scene/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ namespace Atlas {

}

void Scene::Timestep(float deltaTime) {
void Scene::Update(float deltaTime) {

this->deltaTime = deltaTime;

Expand Down Expand Up @@ -145,11 +145,16 @@ namespace Atlas {
if (HasMainCamera()) {
auto& mainCamera = mainCameraEntity.GetComponent<CameraComponent>();

if (terrain.IsLoaded())
terrain->Update(mainCamera);
if (terrain.IsLoaded()) {
JobSystem::Execute(jobGroup, [&](JobData&) {
terrain->Update(mainCamera);
});
}

if (ocean) {
ocean->Update(mainCamera, deltaTime);
JobSystem::Execute(jobGroup, [&](JobData&) {
ocean->Update(mainCamera, deltaTime);
});
}
}

Expand Down Expand Up @@ -344,38 +349,43 @@ namespace Atlas {
meshComponent.inserted = true;
}

// After everything we need to reset transform component changed and prepare the updated for next frame
JobSystem::ParallelFor(jobGroup, int32_t(transformComponentPool.GetCount()), 8, [&](JobData&, int32_t idx) {
auto& transformComponent = transformComponentPool.GetByIndex(idx);
// Don't do anything in parallel here, we don't expect to have many cameras
mainCameraEntity = Entity();
auto cameraSubset = entityManager.GetSubset<CameraComponent>();
// Attempt to find a main camera
for (auto entity : cameraSubset) {
auto& camera = cameraSubset.Get(entity);

if (transformComponent.updated) {
transformComponent.changed = false;
transformComponent.updated = false;
mat4 transformMatrix = mat4(1.0f);
auto transform = entityManager.TryGet<TransformComponent>(entity);
if (transform) {
camera.parentTransform = transform->globalMatrix;
transformMatrix = transform->globalMatrix;
}
});

// After everything we need to reset transform component changed and prepare the updated for next frame
JobSystem::ParallelFor(jobGroup, int32_t(hierarchyComponentPool.GetCount()), 4, [&](JobData&, int32_t idx) {
auto& hierarchyComponent = hierarchyComponentPool.GetByIndex(idx);

hierarchyComponent.updated = false;
});
camera.Update(transformMatrix);

JobSystem::Wait(jobGroup);
if (camera.isMain && !mainCameraEntity.IsValid()) {
mainCameraEntity = { entity, &entityManager };
}
}

auto lightSubset = entityManager.GetSubset<LightComponent>();
for (auto entity : lightSubset) {
auto& lightComponent = lightSubset.Get(entity);
JobGroup lightJobGroup {JobPriority::High};
auto lightComponentPool = entityManager.GetPool<LightComponent>();
JobSystem::ParallelFor(lightJobGroup, int32_t(lightComponentPool.GetCount()), 4, [&](JobData&, int32_t idx) {
auto& lightComponent = lightComponentPool.GetByIndex(idx);
auto entity = lightComponentPool[idx];

// This will lead to threading issues if there are several main lights (which there shouldn't be!)
if (lightComponent.isMain && lightComponent.type == LightType::DirectionalLight)
mainLightEntity = Entity(entity, &entityManager);

auto transformComponent = transformComponentPool.TryGet(entity);

lightComponent.Update(transformComponent);
}
});

renderState.mainCameraSignal.Reset();
JobSystem::Wait(lightJobGroup);

#ifdef AE_BINDLESS
auto rayTracingSubset = GetSubset<MeshComponent, TransformComponent>();
Expand All @@ -396,85 +406,66 @@ namespace Atlas {
});
#endif

// Everything below assumes that entities themselves have a transform
// Without it they won't be transformed when they are in a hierarchy
auto cameraSubset = entityManager.GetSubset<CameraComponent, TransformComponent>();
for (auto entity : cameraSubset) {
const auto& [cameraComponent, transformComponent] = cameraSubset.Get(entity);

cameraComponent.parentTransform = transformComponent.globalMatrix;
}

auto textSubset = entityManager.GetSubset<TextComponent, TransformComponent>();
for (auto entity : textSubset) {
const auto& [textComponent, transformComponent] = textSubset.Get(entity);

textComponent.Update(transformComponent);
}

firstTimestep = false;

}

void Scene::Update() {

mainCameraEntity = Entity();
if (HasMainCamera()) {
auto& mainCamera = GetMainCamera();

auto cameraSubset = entityManager.GetSubset<CameraComponent>();
JobSystem::ParallelFor(lightJobGroup, int32_t(lightComponentPool.GetCount()), 4, [&](JobData&, int32_t idx) {
auto& lightComponent = lightComponentPool.GetByIndex(idx);

lightComponent.Update(mainCamera);
});

// Attempt to find a main camera
for (auto entity : cameraSubset) {
auto& camera = cameraSubset.Get(entity);
auto audioSubset = entityManager.GetSubset<AudioComponent, TransformComponent>();
for (auto entity : audioSubset) {
const auto& [audioComponent, transformComponent] = audioSubset.Get(entity);

mat4 transformMatrix = mat4(1.0f);
auto transform = entityManager.TryGet<TransformComponent>(entity);
if (transform) {
transformMatrix = transform->globalMatrix;
audioComponent.Update(deltaTime, transformComponent, mainCamera.GetLocation(),
mainCamera.GetLastLocation(), mainCamera.right);
}

camera.Update(transformMatrix);
auto audioVolumeSubset = entityManager.GetSubset<AudioVolumeComponent, TransformComponent>();
for (auto entity : audioVolumeSubset) {
const auto& [audioComponent, transformComponent] = audioVolumeSubset.Get(entity);

if (camera.isMain && !mainCameraEntity.IsValid()) {
mainCameraEntity = { entity, &entityManager };
audioComponent.Update(transformComponent, mainCamera.GetLocation());
}
}
}

renderState.mainCameraSignal.Release();
// After everything we need to reset transform component changed and prepare the updated for next frame
JobSystem::ParallelFor(jobGroup, int32_t(transformComponentPool.GetCount()), 8, [&](JobData&, int32_t idx) {
auto& transformComponent = transformComponentPool.GetByIndex(idx);

AE_ASSERT(mainCameraEntity.IsValid() && "Couldn't find main camera component");
if (transformComponent.updated) {
transformComponent.changed = false;
transformComponent.updated = false;
}
});

if (!mainCameraEntity.IsValid())
return;
// After everything we need to reset transform component changed and prepare the updated for next frame
JobSystem::ParallelFor(jobGroup, int32_t(hierarchyComponentPool.GetCount()), 4, [&](JobData&, int32_t idx) {
auto& hierarchyComponent = hierarchyComponentPool.GetByIndex(idx);

auto& mainCamera = mainCameraEntity.GetComponent<CameraComponent>();
hierarchyComponent.updated = false;
});

auto audioSubset = entityManager.GetSubset<AudioComponent, TransformComponent>();
for (auto entity : audioSubset) {
const auto& [audioComponent, transformComponent] = audioSubset.Get(entity);
JobSystem::Wait(lightJobGroup);

audioComponent.Update(deltaTime, transformComponent, mainCamera.GetLocation(),
mainCamera.GetLastLocation(), mainCamera.right);
}
renderState.FillRenderList();
renderState.CullAndSortLights();

auto audioVolumeSubset = entityManager.GetSubset<AudioVolumeComponent, TransformComponent>();
for (auto entity : audioVolumeSubset) {
const auto& [audioComponent, transformComponent] = audioVolumeSubset.Get(entity);
auto textSubset = entityManager.GetSubset<TextComponent, TransformComponent>();
for (auto entity : textSubset) {
const auto& [textComponent, transformComponent] = textSubset.Get(entity);

audioComponent.Update(transformComponent, mainCamera.GetLocation());
textComponent.Update(transformComponent);
}

auto lightSubset = entityManager.GetSubset<LightComponent>();
for (auto entity : lightSubset) {
auto& lightComponent = lightSubset.Get(entity);

lightComponent.Update(mainCamera);
}
firstTimestep = false;

renderState.FillRenderList();
renderState.CullAndSortLights();
JobSystem::Wait(jobGroup);

}

std::vector<ResourceHandle<Mesh::Mesh>> Scene::GetMeshes() {

std::vector<ResourceHandle<Mesh::Mesh>> meshes;
Expand Down
4 changes: 1 addition & 3 deletions src/engine/scene/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,7 @@ namespace Atlas {

std::unordered_map<ECS::Entity, Entity> Merge(const Ref<Scene>& other);

void Timestep(float deltaTime);

void Update();
void Update(float deltaTime);

std::vector<ResourceHandle<Mesh::Mesh>> GetMeshes();

Expand Down
3 changes: 0 additions & 3 deletions src/engine/scene/SceneRenderState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,9 +593,6 @@ namespace Atlas::Scene {

void SceneRenderState::WaitForAsyncWorkCompletion() {

// Assume scene work was done
mainCameraSignal.Release();

JobSystem::Wait(bindlessBlasMapUpdateJob);
JobSystem::Wait(bindlessTextureMapUpdateJob);
JobSystem::Wait(bindlessOtherTextureMapUpdateJob);
Expand Down
2 changes: 0 additions & 2 deletions src/engine/scene/SceneRenderState.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ namespace Atlas::Scene {
std::vector<Renderer::VolumetricLight> volumetricLights;
std::vector<Renderer::Shadow> volumetricShadows;

JobSignal mainCameraSignal;

JobGroup materialUpdateJob{ JobPriority::High };
JobGroup rayTracingWorldUpdateJob{ JobPriority::High };
JobGroup bindlessBlasMapUpdateJob{ JobPriority::High };
Expand Down
5 changes: 2 additions & 3 deletions src/tests/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,7 @@ void App::Update(float deltaTime) {
camera.location += camera.right * moveCameraSpeed * cos(Atlas::Clock::Get());
}

scene->Timestep(deltaTime);
scene->Update();
scene->Update(deltaTime);

CheckLoadScene();

Expand Down Expand Up @@ -331,7 +330,7 @@ bool App::LoadScene() {
meshCount++;
}

scene->Timestep(1.0f);
scene->Update(1.0f);

Atlas::Clock::ResetAverage();

Expand Down

0 comments on commit bb887b9

Please sign in to comment.