Files
HydraV3/HydraEngine/source/buffer/HydraShadowBufferManager.cpp
T

260 lines
12 KiB
C++
Raw Normal View History

2026-08-06 21:11:33 +01:00
#include "HydraShadowBufferManager.h"
#include "../scheduler/HydraTaskScheduler.h"
#include "../task/buffer/HydraCreateGPUBufferTask.hpp"
#include "../task/buffer/HydraUpdateWholeGPUBufferTask.hpp"
#include "../task/buffer/HydraUpdatePartialGPUBufferTask.hpp"
#include "../task/buffer/HydraCreateUnBoundTextureTask.hpp"
2026-08-18 16:23:20 +01:00
#include "../task/buffer/HydraDeleteGPUBufferTask.hpp"
2026-08-06 21:11:33 +01:00
#include "../task/renderer/HydraCreateCascadeShadowFrameBuffer.hpp"
2026-08-18 16:23:20 +01:00
#include "../task/renderer/HydraCreateCubemapShadowFrameBuffer.hpp"
2026-08-06 21:11:33 +01:00
#include "../task/renderer/HydraCreateShadowFrameBuffer.hpp"
2026-08-17 21:44:00 +01:00
#include "../task/renderer/HydraDeleteShadowFrameBufferTask.hpp"
#include "../ecs/components/HydraDirectionalShadowSourceComponent.h"
2026-08-06 21:11:33 +01:00
void HydraShadowBufferManager::Initialise()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
for(uint32_t i = 0; i < MAX_DIRECTIONAL_SHADOWS; i++)
{
m_available_dir.push(i);
}
for(uint32_t i = 0; i < MAX_SPOT_SHADOWS; i++)
{
m_available_spot.push(i);
}
2026-08-16 13:47:11 +01:00
for(uint32_t i = 0; i < MAX_POINT_SHADOWS; i++)
{
m_available_point.push(i);
}
2026-08-06 21:11:33 +01:00
m_directional_shadow_buffer.resize(MAX_DIRECTIONAL_SHADOWS);
m_spot_shadow_buffer.resize(MAX_SPOT_SHADOWS);
2026-08-16 13:47:11 +01:00
m_point_shadow_buffer.resize(MAX_POINT_SHADOWS);
2026-08-06 21:11:33 +01:00
uint32_t buffer_size = (MAX_DIRECTIONAL_SHADOWS * sizeof(HydraDirectionalShadowSourceComponent));
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("DirectionalShadowBuffer", 1, buffer_size, &m_directional_shadow_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
buffer_size = (MAX_SPOT_SHADOWS * sizeof(HydraSpotShadowSourceComponent));
create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
HydraCreateGPUBufferTask *spot_task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
spot_task->Intialise("SpotShadowBuffer", 1, buffer_size, &m_spot_shadow_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
2026-08-16 13:47:11 +01:00
buffer_size = (MAX_POINT_SHADOWS * sizeof(HydraPointShadowSourceComponent));
create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
HydraCreateGPUBufferTask *point_task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
point_task->Intialise("PointShadowBuffer", 1, buffer_size, &m_point_shadow_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
2026-08-06 21:11:33 +01:00
}
void HydraShadowBufferManager::Shutdown()
{
2026-08-18 16:23:20 +01:00
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
HydraDeleteGPUBufferTask *point_task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
point_task->Intialise(m_point_shadow_buffer_id);
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
HydraDeleteGPUBufferTask *dir_task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
dir_task->Intialise(m_directional_shadow_buffer_id);
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
HydraDeleteGPUBufferTask *spot_task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
spot_task->Intialise(m_point_shadow_buffer_id);
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
2026-08-06 21:11:33 +01:00
}
2026-08-18 16:23:20 +01:00
HydraID HydraShadowBufferManager::AddDirectionalShadow(HydraDirectionalShadowSourceComponent& shadow)
2026-08-06 21:11:33 +01:00
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_dir.size() == 0)
{
return INVALID_HYDRA_ID;
}
HydraID shadow_id = m_available_dir.front();
shadow.shadow_id = shadow_id;
m_directional_shadow_buffer[shadow_id] = shadow;
2026-08-18 16:23:20 +01:00
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t depth_texture_id = 0;
uint32_t frame_buffer_id = 0;
HydraID create_framebuffer_task_id = task_scheduler->CreateTask<HydraCreateCascadeShadowFrameBuffer>(HydraThreadAffinity::Render);
HydraCreateCascadeShadowFrameBuffer *fb_task = static_cast<HydraCreateCascadeShadowFrameBuffer *>(task_scheduler->GetTask(create_framebuffer_task_id));
fb_task->Initialise(&depth_texture_id, &frame_buffer_id);
task_scheduler->WaitForTask(create_framebuffer_task_id);
shadow.shadow_texture_id = depth_texture_id;
shadow.frame_buffer_id = frame_buffer_id;
2026-08-06 21:11:33 +01:00
return shadow_id;
}
2026-08-18 16:23:20 +01:00
HydraID HydraShadowBufferManager::AddSpotShadow(HydraSpotShadowSourceComponent& shadow)
2026-08-06 21:11:33 +01:00
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_spot.size() == 0)
{
return INVALID_HYDRA_ID;
}
HydraID shadow_id = m_available_spot.front();
m_spot_shadow_buffer[shadow_id] = shadow;
2026-08-18 16:23:20 +01:00
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t depth_texture_id = 0;
uint32_t frame_buffer_id = 0;
HydraID create_framebuffer_task_id = task_scheduler->CreateTask<HydraCreateShadowFrameBuffer>(HydraThreadAffinity::Render);
HydraCreateShadowFrameBuffer *fb_task = static_cast<HydraCreateShadowFrameBuffer *>(task_scheduler->GetTask(create_framebuffer_task_id));
fb_task->Initialise(&depth_texture_id, &frame_buffer_id);
task_scheduler->WaitForTask(create_framebuffer_task_id);
shadow.shadow_texture_id = depth_texture_id;
shadow.frame_buffer_id = frame_buffer_id;
2026-08-06 21:11:33 +01:00
return shadow_id;
}
2026-08-18 16:23:20 +01:00
HydraID HydraShadowBufferManager::AddPointShadow(HydraPointShadowSourceComponent& shadow)
2026-08-16 13:47:11 +01:00
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_point.size() == 0)
{
return INVALID_HYDRA_ID;
}
HydraID shadow_id = m_available_point.front();
m_point_shadow_buffer[shadow_id] = shadow;
2026-08-18 16:23:20 +01:00
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t depth_texture_id = 0;
uint32_t frame_buffer_id = 0;
HydraID create_framebuffer_task_id = task_scheduler->CreateTask<HydraCreateCubemapShadowFrameBuffer>(HydraThreadAffinity::Render);
HydraCreateCubemapShadowFrameBuffer *fb_task = static_cast<HydraCreateCubemapShadowFrameBuffer *>(task_scheduler->GetTask(create_framebuffer_task_id));
fb_task->Initialise( &depth_texture_id, &frame_buffer_id);
task_scheduler->WaitForTask(create_framebuffer_task_id);
shadow.shadow_texture_id = depth_texture_id;
shadow.frame_buffer_id = frame_buffer_id;
2026-08-16 13:47:11 +01:00
return shadow_id;
}
2026-08-06 21:11:33 +01:00
void HydraShadowBufferManager::UpdateDirectionalShadow(HydraID shadow_id, HydraDirectionalShadowSourceComponent shadow)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(shadow_id < MAX_DIRECTIONAL_SHADOWS)
{
m_directional_shadow_buffer[shadow_id] = shadow;
}
}
void HydraShadowBufferManager::UpdateSpotShadow(HydraID shadow_id, HydraSpotShadowSourceComponent shadow)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(shadow_id < MAX_SPOT_SHADOWS)
{
m_spot_shadow_buffer[shadow_id] = shadow;
}
}
2026-08-16 13:47:11 +01:00
void HydraShadowBufferManager::UpdatePointShadow(HydraID shadow_id, HydraPointShadowSourceComponent shadow)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(shadow_id < MAX_SPOT_SHADOWS)
{
m_point_shadow_buffer[shadow_id] = shadow;
}
}
2026-08-17 21:44:00 +01:00
void HydraShadowBufferManager::DeleteDirectionalShadow(HydraID shadow_id)
2026-08-06 21:11:33 +01:00
{
2026-08-17 21:44:00 +01:00
HydraECS* ecs = GetEngine()->ECS();
HydraTaskScheduler* task_scheduler = GetEngine()->TaskScheduler();
HydraDirectionalShadowSourceComponent shadow_comp = m_directional_shadow_buffer[shadow_id];
2026-08-06 21:11:33 +01:00
2026-08-17 21:44:00 +01:00
HydraID delete_frame_buffer_task_id = task_scheduler->CreateTask<HydraDeleteShadowFrameBufferTask>(HydraThreadAffinity::Render);
HydraDeleteShadowFrameBufferTask *fb_task = static_cast<HydraDeleteShadowFrameBufferTask *>(task_scheduler->GetTask(delete_frame_buffer_task_id));
fb_task->Initialise(shadow_comp.shadow_texture_id, shadow_comp.frame_buffer_id);
task_scheduler->WaitForTask(delete_frame_buffer_task_id);
2026-08-18 16:23:20 +01:00
m_available_dir.push(shadow_id);
2026-08-06 21:11:33 +01:00
}
2026-08-17 21:44:00 +01:00
void HydraShadowBufferManager::DeleteSpotShadow(HydraID shadow_id)
2026-08-06 21:11:33 +01:00
{
2026-08-17 21:44:00 +01:00
HydraECS* ecs = GetEngine()->ECS();
HydraTaskScheduler* task_scheduler = GetEngine()->TaskScheduler();
HydraSpotShadowSourceComponent shadow_comp = m_spot_shadow_buffer[shadow_id];
2026-08-06 21:11:33 +01:00
2026-08-17 21:44:00 +01:00
HydraID delete_frame_buffer_task_id = task_scheduler->CreateTask<HydraDeleteShadowFrameBufferTask>(HydraThreadAffinity::Render);
HydraDeleteShadowFrameBufferTask *fb_task = static_cast<HydraDeleteShadowFrameBufferTask *>(task_scheduler->GetTask(delete_frame_buffer_task_id));
fb_task->Initialise(shadow_comp.shadow_texture_id, shadow_comp.frame_buffer_id);
task_scheduler->WaitForTask(delete_frame_buffer_task_id);
2026-08-18 16:23:20 +01:00
m_available_spot.push(shadow_id);
2026-08-06 21:11:33 +01:00
}
2026-08-17 21:44:00 +01:00
void HydraShadowBufferManager::DeletePointShadow(HydraID shadow_id)
2026-08-16 13:47:11 +01:00
{
2026-08-17 21:44:00 +01:00
HydraECS* ecs = GetEngine()->ECS();
HydraTaskScheduler* task_scheduler = GetEngine()->TaskScheduler();
HydraPointShadowSourceComponent shadow_comp = m_point_shadow_buffer[shadow_id];
HydraID delete_frame_buffer_task_id = task_scheduler->CreateTask<HydraDeleteShadowFrameBufferTask>(HydraThreadAffinity::Render);
HydraDeleteShadowFrameBufferTask *fb_task = static_cast<HydraDeleteShadowFrameBufferTask *>(task_scheduler->GetTask(delete_frame_buffer_task_id));
fb_task->Initialise(shadow_comp.shadow_texture_id, shadow_comp.frame_buffer_id);
task_scheduler->WaitForTask(delete_frame_buffer_task_id);
2026-08-18 16:23:20 +01:00
m_available_point.push(shadow_id);
2026-08-16 13:47:11 +01:00
}
2026-08-06 21:11:33 +01:00
void HydraShadowBufferManager::UpdateShadowBuffer()
{
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
void *buffer = static_cast<void *>(m_directional_shadow_buffer.data());
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateWholeGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdateWholeGPUBufferTask *task = static_cast<HydraUpdateWholeGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
task->Intialise(m_directional_shadow_buffer_id, buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
void *spot_buffer = static_cast<void *>(m_spot_shadow_buffer.data());
update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateWholeGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdateWholeGPUBufferTask *spot_task = static_cast<HydraUpdateWholeGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
spot_task->Intialise(m_spot_shadow_buffer_id, spot_buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
2026-08-16 13:47:11 +01:00
void *point_buffer = static_cast<void *>(m_point_shadow_buffer.data());
update_buffer_task_id = task_scheduler->CreateTask<HydraUpdateWholeGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdateWholeGPUBufferTask *point_task = static_cast<HydraUpdateWholeGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
point_task->Intialise(m_point_shadow_buffer_id, point_buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
2026-08-06 21:11:33 +01:00
}