2026-07-17 15:30:29 +01:00
|
|
|
#include "HydraLightBufferManager.h"
|
2026-08-18 16:23:20 +01:00
|
|
|
#include "../scheduler/HydraTaskScheduler.h"
|
|
|
|
|
#include "../engine/HydraEngine.h"
|
|
|
|
|
#include "../task/buffer/HydraCreateGPUBufferTask.hpp"
|
|
|
|
|
#include "../task/buffer/HydraDeleteGPUBufferTask.hpp"
|
|
|
|
|
#include "../task/buffer/HydraUpdatePartialGPUBufferTask.hpp"
|
|
|
|
|
#include "../ecs/components/HydraLightComponent.h"
|
2026-07-17 15:30:29 +01:00
|
|
|
|
|
|
|
|
void HydraLightBufferManager::Initialise()
|
|
|
|
|
{
|
|
|
|
|
m_light_lookup.resize(MAX_LIGHTS);
|
2026-08-18 16:23:20 +01:00
|
|
|
|
2026-07-17 15:30:29 +01:00
|
|
|
for(uint32_t i = 0; i < MAX_LIGHTS; i ++)
|
|
|
|
|
{
|
|
|
|
|
m_available_lights.push(i);
|
2026-08-18 16:23:20 +01:00
|
|
|
m_light_lookup[i] = INVALID_HYDRA_ID;
|
2026-07-17 15:30:29 +01:00
|
|
|
}
|
2026-08-18 16:23:20 +01:00
|
|
|
|
|
|
|
|
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
|
|
|
|
|
HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
|
|
|
|
|
HydraCreateGPUBufferTask *task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
|
|
|
|
|
task->Intialise("LightBuffer", 1, MAX_LIGHTS * sizeof(HydraLightComponent), &m_light_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
|
|
|
|
|
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
|
2026-07-17 15:30:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HydraLightBufferManager::Shutdown()
|
|
|
|
|
{
|
2026-08-18 16:23:20 +01:00
|
|
|
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
|
|
|
|
|
HydraID delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
|
|
|
|
|
HydraDeleteGPUBufferTask *task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
|
|
|
|
|
task->Intialise(m_light_buffer_id);
|
|
|
|
|
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
|
2026-07-17 15:30:29 +01:00
|
|
|
}
|
|
|
|
|
|
2026-08-18 16:23:20 +01:00
|
|
|
void HydraLightBufferManager::UpdateBuffer()
|
|
|
|
|
{
|
|
|
|
|
void *buffer = static_cast<void *>(m_lights.data());
|
|
|
|
|
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
|
|
|
|
|
|
|
|
|
|
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdatePartialGPUBufferTask>(HydraThreadAffinity::Render);
|
|
|
|
|
HydraUpdatePartialGPUBufferTask *task = static_cast<HydraUpdatePartialGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
|
|
|
|
|
task->Intialise(m_light_buffer_id, 0, sizeof(HydraLightComponent) * m_lights.size(), buffer);
|
|
|
|
|
task_scheduler->WaitForTask(update_buffer_task_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HydraLightBufferManager::AddLight(HydraLightComponent light)
|
2026-07-17 15:30:29 +01:00
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
2026-08-18 16:23:20 +01:00
|
|
|
if(m_available_lights.size() == 0)
|
2026-07-17 15:30:29 +01:00
|
|
|
{
|
2026-08-18 16:23:20 +01:00
|
|
|
return;
|
2026-07-17 15:30:29 +01:00
|
|
|
}
|
|
|
|
|
|
2026-08-18 16:23:20 +01:00
|
|
|
auto it = std::find(m_light_lookup.begin(), m_light_lookup.end(), light.entity_id);
|
|
|
|
|
|
|
|
|
|
if(it == m_light_lookup.end())
|
|
|
|
|
{
|
|
|
|
|
//light ID is not the index in the light buffer - this has to stay contiguous
|
|
|
|
|
m_lights.push_back(light);
|
|
|
|
|
m_light_lookup[m_light_count] = light.entity_id;
|
|
|
|
|
m_light_count++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_lights[m_light_lookup[*it]] = light;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-17 15:30:29 +01:00
|
|
|
}
|
|
|
|
|
|
2026-08-18 16:23:20 +01:00
|
|
|
//Remove the light from the buffer and shuffle all of the others down to keep
|
|
|
|
|
//the light buffer contiguous.
|
|
|
|
|
void HydraLightBufferManager::RemoveLight(HydraID entity_id)
|
2026-07-17 15:30:29 +01:00
|
|
|
{
|
2026-08-18 16:23:20 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
auto it = std::find(m_light_lookup.begin(), m_light_lookup.end(), entity_id);
|
|
|
|
|
if(it != m_light_lookup.end())
|
|
|
|
|
{
|
|
|
|
|
uint32_t remove_idx = it - m_light_lookup.begin();
|
|
|
|
|
//end one - easy
|
|
|
|
|
if(remove_idx == m_light_count-1)
|
|
|
|
|
{
|
|
|
|
|
m_lights.erase(m_lights.end()-1);
|
|
|
|
|
m_light_count--;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-07-17 15:30:29 +01:00
|
|
|
|
2026-08-18 16:23:20 +01:00
|
|
|
|
|
|
|
|
HydraLightComponent light_to_delete = m_lights[remove_idx];
|
|
|
|
|
HydraLightComponent light_to_move = m_lights[m_light_count-1];
|
|
|
|
|
|
|
|
|
|
m_lights[remove_idx] = light_to_move;
|
|
|
|
|
m_lights.erase(m_lights.end()-1);
|
|
|
|
|
m_light_lookup[m_light_count-1] = INVALID_HYDRA_ID;
|
|
|
|
|
m_light_lookup[remove_idx] = light_to_move.entity_id;
|
|
|
|
|
m_light_count--;
|
|
|
|
|
}
|
2026-07-17 15:30:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t HydraLightBufferManager::GetLightCount()
|
|
|
|
|
{
|
|
|
|
|
return m_light_count;
|
|
|
|
|
}
|