Merge branch 'main' into SP3-13-Assets-Manager
This commit is contained in:
commit
4019b4914c
|
@ -0,0 +1,54 @@
|
||||||
|
[Window][MainStatusBar]
|
||||||
|
Pos=0,1060
|
||||||
|
Size=1920,20
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][SHEditorMenuBar]
|
||||||
|
Pos=0,48
|
||||||
|
Size=1920,1012
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Hierarchy Panel]
|
||||||
|
Pos=0,142
|
||||||
|
Size=387,918
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000004,0
|
||||||
|
|
||||||
|
[Window][Debug##Default]
|
||||||
|
Pos=60,60
|
||||||
|
Size=400,400
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Inspector]
|
||||||
|
Pos=1649,48
|
||||||
|
Size=271,1012
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000006,0
|
||||||
|
|
||||||
|
[Window][Profiler]
|
||||||
|
Pos=0,48
|
||||||
|
Size=387,92
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000003,0
|
||||||
|
|
||||||
|
[Window][Viewport]
|
||||||
|
Pos=648,48
|
||||||
|
Size=2519,1319
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000002,0
|
||||||
|
|
||||||
|
[Window][ Viewport]
|
||||||
|
Pos=389,48
|
||||||
|
Size=1258,1012
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000002,0
|
||||||
|
|
||||||
|
[Docking][Data]
|
||||||
|
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X
|
||||||
|
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X
|
||||||
|
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=387,1036 Split=Y Selected=0x1E6EB881
|
||||||
|
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
|
||||||
|
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
|
||||||
|
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1258,1036 CentralNode=1 Selected=0xB41284E7
|
||||||
|
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252
|
||||||
|
|
|
@ -93,6 +93,7 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
|
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>();
|
SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "Physics/Components/SHColliderComponent.h"
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
#include "Camera/SHCameraComponent.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
@ -155,6 +156,10 @@ namespace Sandbox
|
||||||
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
||||||
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||||
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
|
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
|
||||||
|
|
||||||
|
SHComponentManager::AddComponent<SHCameraComponent>(0);
|
||||||
|
SHComponentManager::RemoveComponent <SHRigidBodyComponent>(0);
|
||||||
|
SHComponentManager::RemoveComponent <SHColliderComponent>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Update(float dt)
|
void SBTestScene::Update(float dt)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHCameraComponent.h"
|
#include "SHCameraComponent.h"
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "SHCameraSystem.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -22,33 +24,69 @@ namespace SHADE
|
||||||
void SHCameraComponent::SetYaw(float yaw) noexcept
|
void SHCameraComponent::SetYaw(float yaw) noexcept
|
||||||
{
|
{
|
||||||
this->yaw = yaw;
|
this->yaw = yaw;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 rotation = transform->GetWorldRotation();
|
||||||
|
transform->SetWorldRotation(SHVec3{rotation.x,yaw, rotation.z});
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCameraComponent::SetPitch(float pitch) noexcept
|
void SHCameraComponent::SetPitch(float pitch) noexcept
|
||||||
{
|
{
|
||||||
this->pitch = pitch;
|
this->pitch = pitch;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 rotation = transform->GetWorldRotation();
|
||||||
|
transform->SetWorldRotation(SHVec3{ pitch,rotation.y, rotation.z });
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCameraComponent::SetRoll(float roll) noexcept
|
void SHCameraComponent::SetRoll(float roll) noexcept
|
||||||
{
|
{
|
||||||
this->roll = roll;
|
this->roll = roll;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 rotation = transform->GetWorldRotation();
|
||||||
|
transform->SetWorldRotation(SHVec3{ rotation.x,rotation.y, roll});
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
void SHCameraComponent::SetPositionX(float x) noexcept
|
void SHCameraComponent::SetPositionX(float x) noexcept
|
||||||
{
|
{
|
||||||
position.x = x;
|
position.x = x;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 position = transform->GetWorldPosition();
|
||||||
|
transform->SetWorldRotation(SHVec3{ x,position.y, position.z});
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
void SHCameraComponent::SetPositionY(float y) noexcept
|
void SHCameraComponent::SetPositionY(float y) noexcept
|
||||||
{
|
{
|
||||||
position.y = y;
|
position.y = y;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 position = transform->GetWorldPosition();
|
||||||
|
transform->SetWorldRotation(SHVec3{ position.x,y, position.z });
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
void SHCameraComponent::SetPositionZ(float z) noexcept
|
void SHCameraComponent::SetPositionZ(float z) noexcept
|
||||||
{
|
{
|
||||||
position.z = z;
|
position.z = z;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 position = transform->GetWorldPosition();
|
||||||
|
transform->SetWorldRotation(SHVec3{ position.x,position.y, z });
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
void SHCameraComponent::SetPosition(float x,float y, float z) noexcept
|
void SHCameraComponent::SetPosition(float x,float y, float z) noexcept
|
||||||
|
@ -56,11 +94,23 @@ namespace SHADE
|
||||||
position.x = x;
|
position.x = x;
|
||||||
position.y = y;
|
position.y = y;
|
||||||
position.z = z;
|
position.z = z;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 position = transform->GetWorldPosition();
|
||||||
|
transform->SetWorldRotation(SHVec3{ x,y, z });
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
void SHCameraComponent::SetPosition(SHVec3& pos) noexcept
|
void SHCameraComponent::SetPosition(SHVec3& pos) noexcept
|
||||||
{
|
{
|
||||||
this->position = pos;
|
this->position = pos;
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
|
||||||
|
SHVec3 position = transform->GetWorldPosition();
|
||||||
|
transform->SetWorldRotation(pos);
|
||||||
|
}
|
||||||
dirtyView = true;
|
dirtyView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,4 +178,12 @@ namespace SHADE
|
||||||
return projMatrix;
|
return projMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept
|
||||||
|
{
|
||||||
|
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
system->GetDirector(directorCameraIndex)->SetMainCamera(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,8 @@ namespace SHADE
|
||||||
const SHMatrix& GetViewMatrix() const noexcept;
|
const SHMatrix& GetViewMatrix() const noexcept;
|
||||||
const SHMatrix& GetProjMatrix() const noexcept;
|
const SHMatrix& GetProjMatrix() const noexcept;
|
||||||
|
|
||||||
|
void SetMainCamera(size_t cameraDirectorIndex = 0) noexcept;
|
||||||
|
|
||||||
|
|
||||||
float movementSpeed;
|
float movementSpeed;
|
||||||
SHVec3 turnSpeed;
|
SHVec3 turnSpeed;
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHCameraDirector.h"
|
||||||
|
#include "SHCameraComponent.h"
|
||||||
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Tools/SHLog.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHCameraDirector::SHCameraDirector()
|
||||||
|
:mainCameraEID(MAX_EID), transitionCameraEID(MAX_EID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHMatrix SHCameraDirector::GetViewMatrix() const noexcept
|
||||||
|
{
|
||||||
|
return viewMatrix;
|
||||||
|
}
|
||||||
|
SHMatrix SHCameraDirector::GetProjMatrix() const noexcept
|
||||||
|
{
|
||||||
|
return projMatrix;
|
||||||
|
}
|
||||||
|
SHMatrix SHCameraDirector::GetVPMatrix() const noexcept
|
||||||
|
{
|
||||||
|
return projMatrix * viewMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCameraDirector::UpdateMatrix() noexcept
|
||||||
|
{
|
||||||
|
if (mainCameraEID == MAX_EID)
|
||||||
|
{
|
||||||
|
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
|
||||||
|
if (dense.size() == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mainCameraEID = dense[0].GetEID();
|
||||||
|
}
|
||||||
|
SHCameraComponent* camComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(mainCameraEID);
|
||||||
|
if (!camComponent)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Camera Director warning: Entity does not have a camera");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
viewMatrix = camComponent->GetViewMatrix();
|
||||||
|
projMatrix = camComponent->GetProjMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept
|
||||||
|
{
|
||||||
|
if (SHEntityManager::IsValidEID(camera.GetEID()) == false)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Camera Director Warning: Attempting to set an invalid entity as main camera.")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mainCameraEID = camera.GetEID();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHCameraComponent;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SH_API SHCameraDirector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHCameraDirector();
|
||||||
|
~SHCameraDirector() = default;
|
||||||
|
|
||||||
|
|
||||||
|
EntityID mainCameraEID;
|
||||||
|
EntityID transitionCameraEID;
|
||||||
|
|
||||||
|
SHMatrix GetViewMatrix() const noexcept;
|
||||||
|
SHMatrix GetProjMatrix() const noexcept;
|
||||||
|
SHMatrix GetVPMatrix() const noexcept;
|
||||||
|
void UpdateMatrix() noexcept;
|
||||||
|
void SetMainCamera(SHCameraComponent& cam) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SHMatrix viewMatrix;
|
||||||
|
SHMatrix projMatrix;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Handle<SHCameraDirector> DirectorHandle;
|
||||||
|
|
||||||
|
}
|
|
@ -3,12 +3,63 @@
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
#include "Input/SHInputManager.h"
|
#include "Input/SHInputManager.h"
|
||||||
#include "Math/Vector/SHVec2.h"
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
void SHCameraSystem::UpdateEditorCamera(double dt) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
auto& camera = editorCamera;
|
||||||
|
SHVec3 view, right, UP;
|
||||||
|
GetCameraAxis(camera, view, right, UP);
|
||||||
|
|
||||||
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A))
|
||||||
|
{
|
||||||
|
camera.position -= right * dt * camera.movementSpeed;
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::D))
|
||||||
|
{
|
||||||
|
camera.position += right * dt * camera.movementSpeed;
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W))
|
||||||
|
{
|
||||||
|
camera.position += view * dt * camera.movementSpeed;
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S))
|
||||||
|
{
|
||||||
|
camera.position -= view * dt * camera.movementSpeed;
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q))
|
||||||
|
{
|
||||||
|
camera.position += UP * dt * camera.movementSpeed;
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E))
|
||||||
|
{
|
||||||
|
camera.position -= UP * dt * camera.movementSpeed;
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB))
|
||||||
|
{
|
||||||
|
double mouseX, mouseY;
|
||||||
|
SHInputManager::GetMouseVelocity(&mouseX, &mouseY);
|
||||||
|
|
||||||
|
//std::cout << camera.yaw << std::endl;
|
||||||
|
|
||||||
|
camera.pitch -= mouseY * dt * camera.turnSpeed.x;
|
||||||
|
camera.yaw -= mouseX * dt * camera.turnSpeed.y;
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateCameraComponent(editorCamera);
|
||||||
|
}
|
||||||
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
|
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
|
||||||
{
|
{
|
||||||
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
||||||
|
@ -18,6 +69,7 @@ namespace SHADE
|
||||||
|
|
||||||
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A))
|
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A))
|
||||||
{
|
{
|
||||||
|
//std::cout << "Camera movement: "<<right.x<<", " << right.y << std::endl;
|
||||||
camera.position -= right * dt * camera.movementSpeed;
|
camera.position -= right * dt * camera.movementSpeed;
|
||||||
camera.dirtyView = true;
|
camera.dirtyView = true;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +110,7 @@ namespace SHADE
|
||||||
camera.dirtyView = true;
|
camera.dirtyView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl;
|
||||||
system->UpdateCameraComponent(system->editorCamera);
|
system->UpdateCameraComponent(system->editorCamera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +136,26 @@ namespace SHADE
|
||||||
|
|
||||||
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
|
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
|
||||||
{
|
{
|
||||||
|
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
|
||||||
|
{
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(camera.GetEID());
|
||||||
|
SHVec3 rotation = transform->GetWorldRotation();
|
||||||
|
camera.pitch = SHMath::RadiansToDegrees(rotation.x);
|
||||||
|
camera.yaw = SHMath::RadiansToDegrees(rotation.y);
|
||||||
|
camera.roll = SHMath::RadiansToDegrees(rotation.z);
|
||||||
|
camera.position = transform->GetWorldPosition();
|
||||||
|
camera.dirtyView = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (camera.dirtyView)
|
if (camera.dirtyView)
|
||||||
{
|
{
|
||||||
|
|
||||||
SHVec3 view, right, UP;
|
SHVec3 view, right, UP;
|
||||||
|
|
||||||
|
|
||||||
|
//ClampCameraRotation(camera);
|
||||||
|
|
||||||
GetCameraAxis(camera, view, right, UP);
|
GetCameraAxis(camera, view, right, UP);
|
||||||
|
|
||||||
camera.viewMatrix = SHMatrix::Identity;
|
camera.viewMatrix = SHMatrix::Identity;
|
||||||
|
@ -168,5 +237,55 @@ namespace SHADE
|
||||||
upVec = SHVec3::Cross(forward, right);
|
upVec = SHVec3::Cross(forward, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCameraSystem::CameraSystemUpdate::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
|
||||||
|
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
|
||||||
|
for (auto& cam : dense)
|
||||||
|
{
|
||||||
|
system->UpdateCameraComponent(cam);
|
||||||
|
}
|
||||||
|
for (auto& handle : system->directorHandleList)
|
||||||
|
{
|
||||||
|
handle->UpdateMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirectorHandle SHCameraSystem::CreateDirector() noexcept
|
||||||
|
{
|
||||||
|
auto handle = directorLibrary.Create();
|
||||||
|
directorHandleList.emplace_back(handle);
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectorHandle SHCameraSystem::GetDirector(size_t index) noexcept
|
||||||
|
{
|
||||||
|
if (index < directorHandleList.size())
|
||||||
|
{
|
||||||
|
return directorHandleList[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CreateDirector();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (camera.pitch > 85)
|
||||||
|
camera.SetPitch(85);
|
||||||
|
if (camera.pitch < -85)
|
||||||
|
camera.SetPitch(-85);
|
||||||
|
if (camera.roll > 85)
|
||||||
|
camera.SetRoll(85);
|
||||||
|
if (camera.roll < -85)
|
||||||
|
camera.SetRoll(-85);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
#include "ECS_Base/System/SHSystem.h"
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
#include "SHCameraComponent.h"
|
#include "SHCameraComponent.h"
|
||||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
|
#include "Resource/SHResourceLibrary.h"
|
||||||
|
#include "SHCameraDirector.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SH_API SHCameraSystem final : public SHSystem
|
class SH_API SHCameraSystem final : public SHSystem
|
||||||
|
@ -15,7 +16,8 @@ namespace SHADE
|
||||||
//This is not tied to any entity. Hence this EID should not be used.
|
//This is not tied to any entity. Hence this EID should not be used.
|
||||||
SHCameraComponent editorCamera;
|
SHCameraComponent editorCamera;
|
||||||
|
|
||||||
|
SHResourceLibrary<SHCameraDirector> directorLibrary;
|
||||||
|
std::vector<DirectorHandle> directorHandleList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHCameraSystem(void) = default;
|
SHCameraSystem(void) = default;
|
||||||
|
@ -34,13 +36,26 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
friend class EditorCameraUpdate;
|
friend class EditorCameraUpdate;
|
||||||
|
|
||||||
SHCameraComponent* GetEditorCamera (void) noexcept;
|
class SH_API CameraSystemUpdate final: public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {};
|
||||||
|
virtual void Execute(double dt)noexcept override final;
|
||||||
|
};
|
||||||
|
friend class CameraSystemUpdate;
|
||||||
|
|
||||||
|
|
||||||
|
SHCameraComponent* GetEditorCamera (void) noexcept;
|
||||||
|
void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept;
|
||||||
|
DirectorHandle CreateDirector() noexcept;
|
||||||
|
DirectorHandle GetDirector(size_t index) noexcept;
|
||||||
|
void ClampCameraRotation(SHCameraComponent& camera) noexcept;
|
||||||
|
void UpdateEditorCamera(double dt) noexcept;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
|
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
|
||||||
|
|
||||||
void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
#include "Graphics/Images/SHVkImage.h"
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -299,7 +300,7 @@ namespace SHADE
|
||||||
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. ");
|
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout();
|
bindPointData[static_cast<uint32_t>(pipelineHdl->GetPipelineType())].boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout();
|
||||||
vkCommandBuffer.bindPipeline(pipelineHdl->GetPipelineBindPoint(), pipelineHdl->GetVkPipeline());
|
vkCommandBuffer.bindPipeline(pipelineHdl->GetPipelineBindPoint(), pipelineHdl->GetVkPipeline());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +359,10 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
|
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
|
||||||
{
|
{
|
||||||
vkCommandBuffer.bindDescriptorSets(bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
|
uint32_t bindPointIndex = static_cast<uint32_t>(bindPoint);
|
||||||
|
vkCommandBuffer.bindDescriptorSets(SHVkUtil::GetPipelineBindPointFromType(bindPoint), bindPointData[bindPointIndex].boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -452,6 +454,11 @@ namespace SHADE
|
||||||
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
|
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::ComputeDispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept
|
||||||
|
{
|
||||||
|
vkCommandBuffer.dispatch (groupCountX, groupCountY, groupCountZ);
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo)
|
void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo)
|
||||||
{
|
{
|
||||||
vkCommandBuffer.copyBufferToImage
|
vkCommandBuffer.copyBufferToImage
|
||||||
|
@ -500,9 +507,9 @@ namespace SHADE
|
||||||
// //vkCommandBuffer.pipelineBarrier()
|
// //vkCommandBuffer.pipelineBarrier()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void SHVkCommandBuffer::ForceSetPipelineLayout(Handle<SHVkPipelineLayout> pipelineLayout) noexcept
|
void SHVkCommandBuffer::ForceSetPipelineLayout(Handle<SHVkPipelineLayout> pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept
|
||||||
{
|
{
|
||||||
boundPipelineLayoutHdl = pipelineLayout;
|
bindPointData[static_cast<uint32_t>(pipelineType)].boundPipelineLayoutHdl = pipelineLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -513,12 +520,13 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept
|
void SHVkCommandBuffer::SubmitPushConstants(SH_PIPELINE_TYPE bindPoint) const noexcept
|
||||||
{
|
{
|
||||||
vkCommandBuffer.pushConstants(boundPipelineLayoutHdl->GetVkPipelineLayout(),
|
auto layoutHdl = bindPointData[static_cast<uint32_t>(bindPoint)].boundPipelineLayoutHdl;
|
||||||
boundPipelineLayoutHdl->GetPushConstantInterface().GetShaderStageFlags(),
|
vkCommandBuffer.pushConstants(layoutHdl->GetVkPipelineLayout(),
|
||||||
|
layoutHdl->GetPushConstantInterface().GetShaderStageFlags(),
|
||||||
0,
|
0,
|
||||||
boundPipelineLayoutHdl->GetPushConstantInterface().GetSize(), pushConstantData);
|
layoutHdl->GetPushConstantInterface().GetSize(), pushConstantData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -695,7 +703,7 @@ namespace SHADE
|
||||||
, usageFlags{ rhs.usageFlags }
|
, usageFlags{ rhs.usageFlags }
|
||||||
, commandBufferCount{ rhs.commandBufferCount }
|
, commandBufferCount{ rhs.commandBufferCount }
|
||||||
, parentPool{ rhs.parentPool }
|
, parentPool{ rhs.parentPool }
|
||||||
, boundPipelineLayoutHdl{ rhs.boundPipelineLayoutHdl }
|
, bindPointData{ std::move (rhs.bindPointData)}
|
||||||
{
|
{
|
||||||
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
|
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
|
||||||
|
|
||||||
|
@ -728,7 +736,7 @@ namespace SHADE
|
||||||
usageFlags = rhs.usageFlags;
|
usageFlags = rhs.usageFlags;
|
||||||
commandBufferCount = rhs.commandBufferCount;
|
commandBufferCount = rhs.commandBufferCount;
|
||||||
parentPool = rhs.parentPool;
|
parentPool = rhs.parentPool;
|
||||||
boundPipelineLayoutHdl = rhs.boundPipelineLayoutHdl;
|
bindPointData = std::move(rhs.bindPointData);
|
||||||
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
|
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
|
||||||
|
|
||||||
rhs.vkCommandBuffer = VK_NULL_HANDLE;
|
rhs.vkCommandBuffer = VK_NULL_HANDLE;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "SHCommandPoolResetMode.h"
|
#include "SHCommandPoolResetMode.h"
|
||||||
#include "Resource/SHResourceLibrary.h"
|
#include "Resource/SHResourceLibrary.h"
|
||||||
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
||||||
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -39,7 +40,14 @@ namespace SHADE
|
||||||
friend class SHResourceLibrary<SHVkCommandBuffer>;
|
friend class SHResourceLibrary<SHVkCommandBuffer>;
|
||||||
|
|
||||||
static constexpr uint16_t PUSH_CONSTANT_SIZE = 512;
|
static constexpr uint16_t PUSH_CONSTANT_SIZE = 512;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct PipelineBindPointData
|
||||||
|
{
|
||||||
|
//! The currently bound pipeline
|
||||||
|
Handle<SHVkPipelineLayout> boundPipelineLayoutHdl;
|
||||||
|
};
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -66,8 +74,8 @@ namespace SHADE
|
||||||
//! The command pool that this command buffer belongs to
|
//! The command pool that this command buffer belongs to
|
||||||
Handle<SHVkCommandPool> parentPool;
|
Handle<SHVkCommandPool> parentPool;
|
||||||
|
|
||||||
//! The currently bound pipeline
|
//! Every command buffer will have a set of pipeline bind point specific data
|
||||||
Handle<SHVkPipelineLayout> boundPipelineLayoutHdl;
|
std::array<PipelineBindPointData, static_cast<uint32_t>(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData;
|
||||||
|
|
||||||
//! The push constant data for the command buffer
|
//! The push constant data for the command buffer
|
||||||
uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
|
uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
|
||||||
|
@ -112,13 +120,16 @@ namespace SHADE
|
||||||
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
|
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
|
||||||
void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept;
|
void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept;
|
||||||
void BindIndexBuffer (Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept;
|
void BindIndexBuffer (Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept;
|
||||||
void BindDescriptorSet (Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets);
|
void BindDescriptorSet (Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets);
|
||||||
|
|
||||||
// Draw Commands
|
// Draw Commands
|
||||||
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
|
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
|
||||||
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
|
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
|
||||||
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
|
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
|
||||||
|
|
||||||
|
// Compute Commands
|
||||||
|
void ComputeDispatch (uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept;
|
||||||
|
|
||||||
// Buffer Copy
|
// Buffer Copy
|
||||||
void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
|
void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
|
||||||
void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
|
void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
|
||||||
|
@ -138,13 +149,13 @@ namespace SHADE
|
||||||
|
|
||||||
// Push Constant variable setting
|
// Push Constant variable setting
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetPushConstantVariable(std::string variableName, T const& data) noexcept
|
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept
|
||||||
{
|
{
|
||||||
memcpy (static_cast<uint8_t*>(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T));
|
memcpy (static_cast<uint8_t*>(pushConstantData) + bindPointData[static_cast<uint32_t>(bindPoint)].boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T));
|
||||||
};
|
};
|
||||||
void ForceSetPipelineLayout (Handle<SHVkPipelineLayout> pipelineLayout) noexcept;
|
void ForceSetPipelineLayout (Handle<SHVkPipelineLayout> pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept;
|
||||||
|
|
||||||
void SubmitPushConstants (void) const noexcept;
|
void SubmitPushConstants (SH_PIPELINE_TYPE bindPoint) const noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
|
|
|
@ -25,7 +25,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVkDescriptorPool::SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept
|
SHVkDescriptorPool::SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept
|
||||||
: device{ rhs.device }
|
: ISelfHandle (rhs)
|
||||||
|
, device{ rhs.device }
|
||||||
, pool{ rhs.pool }
|
, pool{ rhs.pool }
|
||||||
{
|
{
|
||||||
rhs.pool = VK_NULL_HANDLE;
|
rhs.pool = VK_NULL_HANDLE;
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace SHADE
|
||||||
|
|
||||||
// new write for the binding
|
// new write for the binding
|
||||||
updater.writeInfos.emplace_back();
|
updater.writeInfos.emplace_back();
|
||||||
updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1);
|
updater.writeHashMap.try_emplace(writeHash, static_cast<uint32_t>(updater.writeInfos.size()) - 1u);
|
||||||
auto& writeInfo = updater.writeInfos.back();
|
auto& writeInfo = updater.writeInfos.back();
|
||||||
|
|
||||||
// Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in
|
// Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in
|
||||||
|
@ -102,10 +102,10 @@ namespace SHADE
|
||||||
//case vk::DescriptorType::eSampler:
|
//case vk::DescriptorType::eSampler:
|
||||||
//case vk::DescriptorType::eSampledImage:
|
//case vk::DescriptorType::eSampledImage:
|
||||||
case vk::DescriptorType::eCombinedImageSampler:
|
case vk::DescriptorType::eCombinedImageSampler:
|
||||||
|
case vk::DescriptorType::eStorageImage:
|
||||||
|
case vk::DescriptorType::eInputAttachment:
|
||||||
writeInfo.descImageInfos.resize(descriptorCount);
|
writeInfo.descImageInfos.resize(descriptorCount);
|
||||||
break;
|
break;
|
||||||
//case vk::DescriptorType::eStorageImage:
|
|
||||||
// break;
|
|
||||||
case vk::DescriptorType::eUniformTexelBuffer:
|
case vk::DescriptorType::eUniformTexelBuffer:
|
||||||
case vk::DescriptorType::eStorageTexelBuffer:
|
case vk::DescriptorType::eStorageTexelBuffer:
|
||||||
case vk::DescriptorType::eUniformBuffer:
|
case vk::DescriptorType::eUniformBuffer:
|
||||||
|
@ -165,6 +165,7 @@ namespace SHADE
|
||||||
if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size())
|
if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. ");
|
SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. ");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
||||||
|
|
|
@ -31,6 +31,8 @@ namespace SHADE
|
||||||
class SHVkDescriptorSetGroup
|
class SHVkDescriptorSetGroup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using viewSamplerLayout = std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Constructor/Destructors */
|
/* Constructor/Destructors */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -233,6 +233,8 @@ namespace SHADE
|
||||||
, vmaAllocator{rhs.vmaAllocator}
|
, vmaAllocator{rhs.vmaAllocator}
|
||||||
, nonDedicatedBestIndex {0}
|
, nonDedicatedBestIndex {0}
|
||||||
, parentPhysicalDeviceHdl {rhs.parentPhysicalDeviceHdl}
|
, parentPhysicalDeviceHdl {rhs.parentPhysicalDeviceHdl}
|
||||||
|
, uboBufferMemoryAlignment{ 0 }
|
||||||
|
, ssboBufferMemoryAlignment{ 0 }
|
||||||
{
|
{
|
||||||
rhs.vkLogicalDevice = VK_NULL_HANDLE;
|
rhs.vkLogicalDevice = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
@ -261,6 +263,8 @@ namespace SHADE
|
||||||
vmaAllocator = rhs.vmaAllocator;
|
vmaAllocator = rhs.vmaAllocator;
|
||||||
nonDedicatedBestIndex = 0;
|
nonDedicatedBestIndex = 0;
|
||||||
parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl;
|
parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl;
|
||||||
|
uboBufferMemoryAlignment = rhs.uboBufferMemoryAlignment;
|
||||||
|
ssboBufferMemoryAlignment = rhs.ssboBufferMemoryAlignment;
|
||||||
|
|
||||||
rhs.vkLogicalDevice = VK_NULL_HANDLE;
|
rhs.vkLogicalDevice = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
@ -529,6 +533,11 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkPipeline> SHVkLogicalDevice::CreateComputePipeline(Handle<SHVkPipelineLayout> const& pipelineLayoutHdl) noexcept
|
||||||
|
{
|
||||||
|
return SHVkInstance::GetResourceManager().Create <SHVkPipeline>(GetHandle(), pipelineLayoutHdl);
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHVkSampler> SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept
|
Handle<SHVkSampler> SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create <SHVkSampler>(GetHandle(), params);
|
return SHVkInstance::GetResourceManager().Create <SHVkSampler>(GetHandle(), params);
|
||||||
|
|
|
@ -181,6 +181,11 @@ namespace SHADE
|
||||||
Handle<SHVkRenderpass> const& renderpassHdl,
|
Handle<SHVkRenderpass> const& renderpassHdl,
|
||||||
Handle<SHSubpass> subpass
|
Handle<SHSubpass> subpass
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
|
Handle<SHVkPipeline> CreateComputePipeline (
|
||||||
|
Handle<SHVkPipelineLayout> const& pipelineLayoutHdl
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
Handle<SHVkSampler> CreateSampler (const SHVkSamplerParams& params) noexcept;
|
Handle<SHVkSampler> CreateSampler (const SHVkSamplerParams& params) noexcept;
|
||||||
|
|
||||||
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
|
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
|
||||||
|
|
|
@ -385,7 +385,7 @@ namespace SHADE
|
||||||
cmdBuffer->BindDescriptorSet
|
cmdBuffer->BindDescriptorSet
|
||||||
(
|
(
|
||||||
matPropsDescSet[frameIndex],
|
matPropsDescSet[frameIndex],
|
||||||
vk::PipelineBindPoint::eGraphics,
|
SH_PIPELINE_TYPE::GRAPHICS,
|
||||||
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
dynamicOffset
|
dynamicOffset
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSuperBatch::SHSuperBatch(Handle<SHSubpass> sp)
|
SHSuperBatch::SHSuperBatch(Handle<SHSubpass> sp)
|
||||||
: subpass { sp }
|
: subpass{ sp }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -63,6 +63,14 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t PER_INSTANCE = 3;
|
static constexpr uint32_t PER_INSTANCE = 3;
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
DescriptorSet Index for render graph resources.
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,23 @@ namespace SHADE
|
||||||
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: This is VERY temporarily here until a more solid resource management system is implemented
|
||||||
|
shaderSourceLibrary.Init("../../TempShaderFolder/");
|
||||||
|
|
||||||
|
shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true);
|
||||||
|
shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true);
|
||||||
|
|
||||||
|
shaderSourceLibrary.LoadShader(2, "KirschCs.glsl", SH_SHADER_TYPE::COMPUTE, true);
|
||||||
|
|
||||||
|
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
|
||||||
|
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
||||||
|
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
||||||
|
auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
|
||||||
|
cubeVS->Reflect();
|
||||||
|
cubeFS->Reflect();
|
||||||
|
greyscale->Reflect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||||
|
@ -130,6 +147,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto windowDims = window->GetWindowSize();
|
auto windowDims = window->GetWindowSize();
|
||||||
|
|
||||||
|
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
|
||||||
// Set Up Cameras
|
// Set Up Cameras
|
||||||
screenCamera = resourceManager.Create<SHCamera>();
|
screenCamera = resourceManager.Create<SHCamera>();
|
||||||
|
@ -154,21 +172,21 @@ namespace SHADE
|
||||||
|
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
worldRenderGraph->Init(device, swapchain);
|
worldRenderGraph->Init(device, swapchain);
|
||||||
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second);
|
worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||||
|
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||||
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||||
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
|
|
||||||
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors
|
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene", "Scene Pre-Process"}, {}); // no predecessors
|
||||||
|
|
||||||
//First subpass to write to G-Buffer
|
//First subpass to write to G-Buffer
|
||||||
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
||||||
gBufferWriteSubpass->AddColorOutput("Scene");
|
gBufferWriteSubpass->AddColorOutput("Scene Pre-Process");
|
||||||
gBufferWriteSubpass->AddColorOutput("Entity ID");
|
gBufferWriteSubpass->AddColorOutput("Entity ID");
|
||||||
gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
||||||
|
|
||||||
// We do this to just transition our scene layout to shader read
|
auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
|
||||||
auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition");
|
node->AddNodeCompute (greyscale, {"Scene Pre-Process", "Scene"});
|
||||||
sceneLayoutTransitionSubpass->AddInput("Scene");
|
|
||||||
|
|
||||||
// Generate world render graph
|
// Generate world render graph
|
||||||
worldRenderGraph->Generate();
|
worldRenderGraph->Generate();
|
||||||
|
@ -177,20 +195,13 @@ namespace SHADE
|
||||||
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||||
worldRenderer->SetCamera(worldCamera);
|
worldRenderer->SetCamera(worldCamera);
|
||||||
|
|
||||||
|
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
|
||||||
|
|
||||||
// TODO: This is VERY temporarily here until a more solid resource management system is implemented
|
|
||||||
shaderSourceLibrary.Init("../../TempShaderFolder/");
|
|
||||||
|
|
||||||
shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true);
|
|
||||||
shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true);
|
|
||||||
|
|
||||||
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
|
|
||||||
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
|
||||||
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
|
||||||
cubeVS->Reflect();
|
|
||||||
cubeFS->Reflect();
|
|
||||||
|
|
||||||
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
|
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||||
|
@ -323,21 +334,7 @@ namespace SHADE
|
||||||
|
|
||||||
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
|
||||||
|
|
||||||
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
if (editorSystem->editorState != SHEditor::State::PLAY)
|
|
||||||
{
|
|
||||||
worldRenderer->SetViewProjectionMatrix(SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// main camera
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
// main camera
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For every viewport
|
// For every viewport
|
||||||
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
||||||
|
@ -360,7 +357,7 @@ namespace SHADE
|
||||||
uint32_t h = static_cast<uint32_t>(viewports[vpIndex]->GetHeight());
|
uint32_t h = static_cast<uint32_t>(viewports[vpIndex]->GetHeight());
|
||||||
currentCmdBuffer->SetViewportScissor (static_cast<float>(w), static_cast<float>(h), w, h);
|
currentCmdBuffer->SetViewportScissor (static_cast<float>(w), static_cast<float>(h), w, h);
|
||||||
|
|
||||||
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout());
|
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS);
|
||||||
|
|
||||||
// Bind all the buffers required for meshes
|
// Bind all the buffers required for meshes
|
||||||
for (auto& [buffer, bindingPoint] : MESH_DATA)
|
for (auto& [buffer, bindingPoint] : MESH_DATA)
|
||||||
|
@ -380,14 +377,29 @@ namespace SHADE
|
||||||
currentCmdBuffer->BindDescriptorSet
|
currentCmdBuffer->BindDescriptorSet
|
||||||
(
|
(
|
||||||
textureDescSet,
|
textureDescSet,
|
||||||
vk::PipelineBindPoint::eGraphics,
|
SH_PIPELINE_TYPE::GRAPHICS,
|
||||||
0,
|
0,
|
||||||
texDynamicOffset
|
texDynamicOffset
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind camera data
|
// bind camera data
|
||||||
|
//renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||||
|
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
if (renderers[renIndex] == worldRenderer)
|
||||||
|
{
|
||||||
|
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editorSystem->editorState != SHEditor::State::PLAY)
|
||||||
|
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix()));
|
||||||
|
else
|
||||||
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||||
|
#else
|
||||||
|
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Draw first
|
// Draw first
|
||||||
renderers[renIndex]->Draw(frameIndex, descPool);
|
renderers[renIndex]->Draw(frameIndex, descPool);
|
||||||
|
@ -726,8 +738,8 @@ namespace SHADE
|
||||||
|
|
||||||
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
cameraSystem->GetEditorCamera()->SetWidth(resizeWidth);
|
cameraSystem->GetEditorCamera()->SetWidth(static_cast<float>(resizeWidth));
|
||||||
cameraSystem->GetEditorCamera()->SetHeight(resizeHeight);
|
cameraSystem->GetEditorCamera()->SetHeight(static_cast<float>(resizeHeight));
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
std::vector combinedImageSampler
|
std::vector combinedImageSampler
|
||||||
{
|
{
|
||||||
std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal),
|
std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eGeneral),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change
|
// Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change
|
||||||
|
|
|
@ -21,6 +21,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
#include "Camera/SHCameraDirector.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -65,6 +66,11 @@ namespace SHADE
|
||||||
camera = _camera;
|
camera = _camera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderer::SetCameraDirector(Handle<SHCameraDirector> director) noexcept
|
||||||
|
{
|
||||||
|
cameraDirector = director;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Drawing Functions */
|
/* Drawing Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -75,15 +81,22 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
if (camera)
|
if (camera && cameraDirector)
|
||||||
{
|
{
|
||||||
|
UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept
|
||||||
|
{
|
||||||
|
SetViewProjectionMatrix(exteriorMatrix);
|
||||||
|
|
||||||
//cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
//cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
||||||
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
||||||
|
|
||||||
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
||||||
|
|
||||||
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
|
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace SHADE
|
||||||
class SHGraphicsGlobalData;
|
class SHGraphicsGlobalData;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
class SHVkBuffer;
|
class SHVkBuffer;
|
||||||
|
class SHCameraDirector;
|
||||||
|
|
||||||
struct SHShaderCameraData
|
struct SHShaderCameraData
|
||||||
{
|
{
|
||||||
|
@ -71,12 +72,14 @@ namespace SHADE
|
||||||
/* Camera Registration */
|
/* Camera Registration */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void SetCamera(Handle<SHCamera> _camera);
|
void SetCamera(Handle<SHCamera> _camera);
|
||||||
|
void SetCameraDirector (Handle<SHCameraDirector> director) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Drawing Functions */
|
/* Drawing Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void UpdateDataAndBind (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept;
|
||||||
void UpdateCameraDataToBuffer (void) noexcept;
|
void UpdateCameraDataToBuffer (void) noexcept;
|
||||||
void SetViewProjectionMatrix (SHMatrix const& vpMatrix) noexcept;
|
void SetViewProjectionMatrix (SHMatrix const& vpMatrix) noexcept;
|
||||||
|
|
||||||
|
@ -99,6 +102,8 @@ namespace SHADE
|
||||||
Handle<SHVkDescriptorSetGroup> cameraDescriptorSet;
|
Handle<SHVkDescriptorSetGroup> cameraDescriptorSet;
|
||||||
Handle<SHVkBuffer> cameraBuffer;
|
Handle<SHVkBuffer> cameraBuffer;
|
||||||
|
|
||||||
|
Handle<SHCameraDirector> cameraDirector;
|
||||||
|
|
||||||
// we really only need 1 copy even though we need %swapchainImages copies for
|
// we really only need 1 copy even though we need %swapchainImages copies for
|
||||||
// GPU.
|
// GPU.
|
||||||
SHShaderCameraData cpuCameraData;
|
SHShaderCameraData cpuCameraData;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHPipelineLibrary::CreateDrawPipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept
|
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept
|
||||||
{
|
{
|
||||||
SHPipelineLayoutParams params
|
SHPipelineLayoutParams params
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ namespace SHADE
|
||||||
newPipeline->ConstructPipeline();
|
newPipeline->ConstructPipeline();
|
||||||
|
|
||||||
// Emplace the new pipeline
|
// Emplace the new pipeline
|
||||||
pipelines.emplace (vsFsPair, newPipeline);
|
graphicsPipelines.emplace (vsFsPair, newPipeline);
|
||||||
|
|
||||||
return newPipeline;
|
return newPipeline;
|
||||||
}
|
}
|
||||||
|
@ -62,19 +62,19 @@ namespace SHADE
|
||||||
logicalDevice = device;
|
logicalDevice = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHPipelineLibrary::GetDrawPipline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
|
Handle<SHVkPipeline> SHPipelineLibrary::GetGraphicsPipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
|
||||||
{
|
{
|
||||||
// return the pipeline requested for
|
// return the pipeline requested for
|
||||||
if (pipelines.contains(vsFsPair))
|
if (graphicsPipelines.contains(vsFsPair))
|
||||||
return pipelines.at(vsFsPair);
|
return graphicsPipelines.at(vsFsPair);
|
||||||
else
|
else
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHPipelineLibrary::CheckDrawPipelineExistence(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
|
bool SHPipelineLibrary::CheckGraphicsPipelineExistence(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
|
||||||
{
|
{
|
||||||
// Returns if a pipeline exists or not
|
// Returns if a pipeline exists or not
|
||||||
return pipelines.contains(vsFsPair);
|
return graphicsPipelines.contains(vsFsPair);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,19 +23,19 @@ namespace SHADE
|
||||||
Handle<SHVkLogicalDevice> logicalDevice;
|
Handle<SHVkLogicalDevice> logicalDevice;
|
||||||
|
|
||||||
//! a map of pipelines that are hashed using a pair of shader module handles
|
//! a map of pipelines that are hashed using a pair of shader module handles
|
||||||
std::unordered_map<std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>>, Handle<SHVkPipeline>> pipelines;
|
std::unordered_map<std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>>, Handle<SHVkPipeline>> graphicsPipelines;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init (Handle<SHVkLogicalDevice> device) noexcept;
|
void Init (Handle<SHVkLogicalDevice> device) noexcept;
|
||||||
|
|
||||||
// Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader
|
// Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader
|
||||||
Handle<SHVkPipeline> CreateDrawPipeline (
|
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
||||||
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
||||||
Handle<SHVkRenderpass> renderpass,
|
Handle<SHVkRenderpass> renderpass,
|
||||||
Handle<SHSubpass> subpass
|
Handle<SHSubpass> subpass
|
||||||
) noexcept;
|
) noexcept;
|
||||||
Handle<SHVkPipeline> GetDrawPipline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
bool CheckDrawPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
enum class SH_PIPELINE_TYPE
|
enum class SH_PIPELINE_TYPE
|
||||||
{
|
{
|
||||||
GRAPHICS,
|
GRAPHICS = 0,
|
||||||
COMPUTE,
|
COMPUTE,
|
||||||
|
RAY_TRACING,
|
||||||
|
NUM_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -4,6 +4,7 @@
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
#include "Graphics/Debugging/SHVulkanDebugUtil.h"
|
#include "Graphics/Debugging/SHVulkanDebugUtil.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
||||||
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -171,6 +172,29 @@ namespace SHADE
|
||||||
|
|
||||||
void SHVkPipeline::CreateComputePipeline(void) noexcept
|
void SHVkPipeline::CreateComputePipeline(void) noexcept
|
||||||
{
|
{
|
||||||
|
auto shaderModule = pipelineLayout->GetShaderModules()[0];
|
||||||
|
|
||||||
|
vk::PipelineShaderStageCreateInfo shaderStageCreateInfo
|
||||||
|
{
|
||||||
|
.stage = vk::ShaderStageFlagBits::eCompute,
|
||||||
|
.module = shaderModule->GetVkShaderModule(),
|
||||||
|
.pName = shaderModule->GetEntryPoint().c_str(),
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::ComputePipelineCreateInfo cpCreateInfo
|
||||||
|
{
|
||||||
|
.flags = {},
|
||||||
|
.stage = shaderStageCreateInfo,
|
||||||
|
.layout = pipelineLayout->GetVkPipelineLayout(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createComputePipelines({}, 1, &cpCreateInfo, nullptr, &vkPipeline); result != vk::Result::eSuccess)
|
||||||
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to create Compute Pipeline. ");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Compute Pipeline. ");
|
||||||
|
created = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +269,7 @@ namespace SHADE
|
||||||
, logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
, logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
||||||
, pipelineLayout { rhs.pipelineLayout }
|
, pipelineLayout { rhs.pipelineLayout }
|
||||||
{
|
{
|
||||||
vkPipeline = VK_NULL_HANDLE;
|
rhs.vkPipeline = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -285,6 +309,7 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkPipeline::~SHVkPipeline(void) noexcept
|
SHVkPipeline::~SHVkPipeline(void) noexcept
|
||||||
{
|
{
|
||||||
|
if (vkPipeline)
|
||||||
logicalDeviceHdl->GetVkLogicalDevice().destroyPipeline(vkPipeline, nullptr);
|
logicalDeviceHdl->GetVkLogicalDevice().destroyPipeline(vkPipeline, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +338,7 @@ namespace SHADE
|
||||||
created = rhs.created;
|
created = rhs.created;
|
||||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||||
|
|
||||||
vkPipeline = VK_NULL_HANDLE;
|
rhs.vkPipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -399,18 +424,7 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
vk::PipelineBindPoint SHVkPipeline::GetPipelineBindPoint(void) const noexcept
|
vk::PipelineBindPoint SHVkPipeline::GetPipelineBindPoint(void) const noexcept
|
||||||
{
|
{
|
||||||
switch (pipelineType)
|
return SHVkUtil::GetPipelineBindPointFromType(pipelineType);
|
||||||
{
|
|
||||||
case SH_PIPELINE_TYPE::GRAPHICS:
|
|
||||||
return vk::PipelineBindPoint::eGraphics;
|
|
||||||
case SH_PIPELINE_TYPE::COMPUTE:
|
|
||||||
return vk::PipelineBindPoint::eCompute;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return vk::PipelineBindPoint::eGraphics;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -450,4 +464,9 @@ namespace SHADE
|
||||||
return pipelineLayout;
|
return pipelineLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SH_PIPELINE_TYPE SHVkPipeline::GetPipelineType(void) const noexcept
|
||||||
|
{
|
||||||
|
return pipelineType;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -77,6 +77,7 @@ namespace SHADE
|
||||||
vk::Pipeline GetVkPipeline (void) const noexcept;
|
vk::Pipeline GetVkPipeline (void) const noexcept;
|
||||||
bool GetIsCreated (void) const noexcept;
|
bool GetIsCreated (void) const noexcept;
|
||||||
Handle<SHVkPipelineLayout> GetPipelineLayout (void) const noexcept;
|
Handle<SHVkPipelineLayout> GetPipelineLayout (void) const noexcept;
|
||||||
|
SH_PIPELINE_TYPE GetPipelineType (void) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,9 +216,18 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkPipelineLayout::PrepareVkDescriptorSetLayouts(void) noexcept
|
void SHVkPipelineLayout::PrepareVkDescriptorSetLayouts(void) noexcept
|
||||||
{
|
{
|
||||||
|
// pipeline layouts contain global layouts first, then layouts for allocation
|
||||||
descriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size());
|
descriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size());
|
||||||
|
vkDescriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size());
|
||||||
|
|
||||||
// Settle allocate layouts first
|
// First we insert the global layouts
|
||||||
|
for (auto const& layout : descriptorSetLayoutsGlobal)
|
||||||
|
{
|
||||||
|
descriptorSetLayoutsPipeline.emplace_back(layout);
|
||||||
|
//vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then the allocate layouts
|
||||||
vkDescriptorSetLayoutsAllocate.reserve(descriptorSetLayoutsAllocate.size());
|
vkDescriptorSetLayoutsAllocate.reserve(descriptorSetLayoutsAllocate.size());
|
||||||
for (auto const& layout : descriptorSetLayoutsAllocate)
|
for (auto const& layout : descriptorSetLayoutsAllocate)
|
||||||
{
|
{
|
||||||
|
@ -226,18 +235,13 @@ namespace SHADE
|
||||||
vkDescriptorSetLayoutsAllocate.emplace_back(layout->GetVkHandle());
|
vkDescriptorSetLayoutsAllocate.emplace_back(layout->GetVkHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
// pipeline layouts contain global layouts first, then layouts for allocation
|
for (auto const& layout : descriptorSetLayoutsPipeline)
|
||||||
vkDescriptorSetLayoutsPipeline.reserve(descriptorSetLayoutsAllocate.size() + descriptorSetLayoutsGlobal.size());
|
|
||||||
|
|
||||||
// First we insert the global layouts
|
|
||||||
for (auto const& layout : descriptorSetLayoutsGlobal)
|
|
||||||
{
|
{
|
||||||
descriptorSetLayoutsPipeline.emplace_back(layout);
|
|
||||||
vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle());
|
vkDescriptorSetLayoutsPipeline.emplace_back(layout->GetVkHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then we append layouts for allocation at the back of the vector
|
// Then we append layouts for allocation at the back of the vector
|
||||||
std::copy(vkDescriptorSetLayoutsAllocate.begin(), vkDescriptorSetLayoutsAllocate.end(), std::back_inserter(vkDescriptorSetLayoutsPipeline));
|
//std::copy(vkDescriptorSetLayoutsAllocate.begin(), vkDescriptorSetLayoutsAllocate.end(), std::back_inserter(vkDescriptorSetLayoutsPipeline));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -294,6 +298,7 @@ namespace SHADE
|
||||||
, descriptorSetLayoutsGlobal{pipelineLayoutParams.globalDescSetLayouts } // do a copy, some other pipeline layout might need this
|
, descriptorSetLayoutsGlobal{pipelineLayoutParams.globalDescSetLayouts } // do a copy, some other pipeline layout might need this
|
||||||
, descriptorSetLayoutsAllocate{}
|
, descriptorSetLayoutsAllocate{}
|
||||||
, vkDescriptorSetLayoutsAllocate{}
|
, vkDescriptorSetLayoutsAllocate{}
|
||||||
|
, descriptorSetLayoutsPipeline{}
|
||||||
, vkDescriptorSetLayoutsPipeline{}
|
, vkDescriptorSetLayoutsPipeline{}
|
||||||
{
|
{
|
||||||
for (auto& mod : shaderModules)
|
for (auto& mod : shaderModules)
|
||||||
|
@ -318,6 +323,7 @@ namespace SHADE
|
||||||
, descriptorSetLayoutsGlobal{}
|
, descriptorSetLayoutsGlobal{}
|
||||||
, descriptorSetLayoutsAllocate{}
|
, descriptorSetLayoutsAllocate{}
|
||||||
, vkDescriptorSetLayoutsAllocate{}
|
, vkDescriptorSetLayoutsAllocate{}
|
||||||
|
, descriptorSetLayoutsPipeline{}
|
||||||
, vkDescriptorSetLayoutsPipeline{}
|
, vkDescriptorSetLayoutsPipeline{}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -368,7 +374,8 @@ namespace SHADE
|
||||||
, descriptorSetLayoutsGlobal {std::move (rhs.descriptorSetLayoutsGlobal)}
|
, descriptorSetLayoutsGlobal {std::move (rhs.descriptorSetLayoutsGlobal)}
|
||||||
, descriptorSetLayoutsAllocate {std::move (rhs.descriptorSetLayoutsAllocate)}
|
, descriptorSetLayoutsAllocate {std::move (rhs.descriptorSetLayoutsAllocate)}
|
||||||
, vkDescriptorSetLayoutsAllocate{std::move (rhs.vkDescriptorSetLayoutsAllocate)}
|
, vkDescriptorSetLayoutsAllocate{std::move (rhs.vkDescriptorSetLayoutsAllocate)}
|
||||||
, vkDescriptorSetLayoutsPipeline{std::move (rhs.vkDescriptorSetLayoutsAllocate)}
|
, descriptorSetLayoutsPipeline { std::move(rhs.descriptorSetLayoutsPipeline) }
|
||||||
|
, vkDescriptorSetLayoutsPipeline{ std::move(rhs.vkDescriptorSetLayoutsPipeline) }
|
||||||
{
|
{
|
||||||
rhs.vkPipelineLayout = VK_NULL_HANDLE;
|
rhs.vkPipelineLayout = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
@ -441,12 +448,12 @@ namespace SHADE
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> SHVkPipelineLayout::GetDescriptorSetLayoutsPipeline(void) const noexcept
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& SHVkPipelineLayout::GetDescriptorSetLayoutsPipeline(void) const noexcept
|
||||||
{
|
{
|
||||||
return descriptorSetLayoutsPipeline;
|
return descriptorSetLayoutsPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> SHVkPipelineLayout::GetDescriptorSetLayoutsAllocate(void) const noexcept
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& SHVkPipelineLayout::GetDescriptorSetLayoutsAllocate(void) const noexcept
|
||||||
{
|
{
|
||||||
return descriptorSetLayoutsAllocate;
|
return descriptorSetLayoutsAllocate;
|
||||||
}
|
}
|
||||||
|
@ -464,7 +471,8 @@ namespace SHADE
|
||||||
descriptorSetLayoutsGlobal = std::move(rhs.descriptorSetLayoutsGlobal);
|
descriptorSetLayoutsGlobal = std::move(rhs.descriptorSetLayoutsGlobal);
|
||||||
descriptorSetLayoutsAllocate = std::move(rhs.descriptorSetLayoutsAllocate);
|
descriptorSetLayoutsAllocate = std::move(rhs.descriptorSetLayoutsAllocate);
|
||||||
vkDescriptorSetLayoutsAllocate = std::move(rhs.vkDescriptorSetLayoutsAllocate);
|
vkDescriptorSetLayoutsAllocate = std::move(rhs.vkDescriptorSetLayoutsAllocate);
|
||||||
vkDescriptorSetLayoutsPipeline = std::move(rhs.vkDescriptorSetLayoutsAllocate);
|
descriptorSetLayoutsPipeline = std::move(rhs.descriptorSetLayoutsPipeline);
|
||||||
|
vkDescriptorSetLayoutsPipeline = std::move(rhs.vkDescriptorSetLayoutsPipeline);
|
||||||
|
|
||||||
rhs.vkPipelineLayout = VK_NULL_HANDLE;
|
rhs.vkPipelineLayout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,8 @@ namespace SHADE
|
||||||
vk::PipelineLayout GetVkPipelineLayout (void) const noexcept;
|
vk::PipelineLayout GetVkPipelineLayout (void) const noexcept;
|
||||||
SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept;
|
SHPushConstantInterface const& GetPushConstantInterface (void) const noexcept;
|
||||||
Handle<SHShaderBlockInterface> GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept;
|
Handle<SHShaderBlockInterface> GetShaderBlockInterface (uint32_t set, uint32_t binding, vk::ShaderStageFlagBits shaderStage) const noexcept;
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> GetDescriptorSetLayoutsPipeline(void) const noexcept;
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescriptorSetLayoutsPipeline(void) const noexcept;
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> GetDescriptorSetLayoutsAllocate(void) const noexcept;
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescriptorSetLayoutsAllocate(void) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ namespace SHADE
|
||||||
DEPTH = 0x04,
|
DEPTH = 0x04,
|
||||||
STENCIL = 0x08,
|
STENCIL = 0x08,
|
||||||
DEPTH_STENCIL = 0x10,
|
DEPTH_STENCIL = 0x10,
|
||||||
INPUT = 0x20
|
INPUT = 0x20,
|
||||||
|
STORAGE = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
#include "SHAttachmentDescInitParams.h"
|
#include "SHAttachmentDescInitParams.h"
|
||||||
|
#include "SHRenderGraphStorage.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -52,12 +54,12 @@ namespace SHADE
|
||||||
// If we set to
|
// If we set to
|
||||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||||
{
|
{
|
||||||
w = swapchainHdl->GetSwapchainImage(0)->GetWidth();
|
w = renderGraphStorage->swapchain->GetSwapchainImage(0)->GetWidth();
|
||||||
h = swapchainHdl->GetSwapchainImage(0)->GetHeight();
|
h = renderGraphStorage->swapchain->GetSwapchainImage(0)->GetHeight();
|
||||||
format = swapchainHdl->GetSurfaceFormatKHR().format;
|
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphResources.try_emplace(resourceName, resourceManager->Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags));
|
renderGraphStorage->graphResources->try_emplace(resourceName, resourceManager->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -77,36 +79,38 @@ namespace SHADE
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& node : nodes)
|
for (uint32_t i = 0; auto& node : nodes)
|
||||||
{
|
{
|
||||||
// key is handle ID, value is pair (first is initial layout, second is final layout).
|
// key is handle ID, value is final layout.
|
||||||
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttLayouts;
|
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
||||||
if (node->subpasses.empty())
|
if (node->subpasses.empty())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. ");
|
SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attempt to get all final layouts for all resources
|
||||||
for (auto& subpass : node->subpasses)
|
for (auto& subpass : node->subpasses)
|
||||||
{
|
{
|
||||||
for (auto& color : subpass->colorReferences)
|
for (auto& color : subpass->colorReferences)
|
||||||
{
|
{
|
||||||
|
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
||||||
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
|
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
|
||||||
resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
||||||
else
|
else
|
||||||
resourceAttLayouts[color.attachment] = color.layout;
|
resourceAttFinalLayouts[color.attachment] = color.layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& depth : subpass->depthReferences)
|
for (auto& depth : subpass->depthReferences)
|
||||||
resourceAttLayouts[depth.attachment] = depth.layout;
|
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
||||||
|
|
||||||
for (auto& input : subpass->inputReferences)
|
for (auto& input : subpass->inputReferences)
|
||||||
resourceAttLayouts[input.attachment] = input.layout;
|
resourceAttFinalLayouts[input.attachment] = input.layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
||||||
{
|
{
|
||||||
auto& att = node->attachmentDescriptions[j];
|
auto& att = node->attachmentDescriptions[j];
|
||||||
att.initialLayout = vk::ImageLayout::eUndefined;
|
att.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
att.finalLayout = resourceAttLayouts[j];
|
att.finalLayout = resourceAttFinalLayouts[j];
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -292,6 +296,9 @@ namespace SHADE
|
||||||
dep.dstAccessMask = dstAccess;
|
dep.dstAccessMask = dstAccess;
|
||||||
|
|
||||||
dep.srcStageMask = srcStage;
|
dep.srcStageMask = srcStage;
|
||||||
|
|
||||||
|
// initialize input descriptors
|
||||||
|
node->subpasses[i]->CreateInputDescriptors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,10 +350,18 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::Init(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept
|
void SHRenderGraph::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept
|
||||||
{
|
{
|
||||||
logicalDeviceHdl = logicalDevice;
|
resourceManager = std::make_shared<SHResourceHub>();
|
||||||
swapchainHdl = swapchain;
|
|
||||||
|
renderGraphStorage = resourceManager->Create<SHRenderGraphStorage>();
|
||||||
|
renderGraphStorage->graphResources = resourceManager->Create<std::unordered_map<std::string, Handle<SHRenderGraphResource>>>();
|
||||||
|
|
||||||
|
renderGraphStorage->logicalDevice = logicalDevice;
|
||||||
|
renderGraphStorage->swapchain = swapchain;
|
||||||
|
|
||||||
|
renderGraphStorage->resourceManager = resourceManager;
|
||||||
|
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -361,21 +376,16 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraph::SHRenderGraph(void) noexcept
|
SHRenderGraph::SHRenderGraph(void) noexcept
|
||||||
: logicalDeviceHdl{ }
|
: renderGraphStorage{}
|
||||||
, swapchainHdl{ }
|
|
||||||
, nodes{}
|
, nodes{}
|
||||||
, graphResources{}
|
|
||||||
, resourceManager{nullptr}
|
, resourceManager{nullptr}
|
||||||
{
|
{
|
||||||
resourceManager = std::make_shared<SHResourceHub>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept
|
SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept
|
||||||
: logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
: renderGraphStorage{ rhs.renderGraphStorage }
|
||||||
, swapchainHdl{ rhs.swapchainHdl }
|
|
||||||
, nodeIndexing{ std::move(rhs.nodeIndexing) }
|
, nodeIndexing{ std::move(rhs.nodeIndexing) }
|
||||||
, nodes{ std::move(rhs.nodes) }
|
, nodes{ std::move(rhs.nodes) }
|
||||||
, graphResources{ std::move(rhs.graphResources) }
|
|
||||||
, resourceManager{ std::move(rhs.resourceManager) }
|
, resourceManager{ std::move(rhs.resourceManager) }
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -386,11 +396,9 @@ namespace SHADE
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
renderGraphStorage = rhs.renderGraphStorage;
|
||||||
swapchainHdl = rhs.swapchainHdl;
|
|
||||||
nodeIndexing = std::move(rhs.nodeIndexing);
|
nodeIndexing = std::move(rhs.nodeIndexing);
|
||||||
nodes = std::move(rhs.nodes);
|
nodes = std::move(rhs.nodes);
|
||||||
graphResources = std::move(rhs.graphResources);
|
|
||||||
resourceManager = std::move(rhs.resourceManager);
|
resourceManager = std::move(rhs.resourceManager);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -426,12 +434,12 @@ namespace SHADE
|
||||||
for (auto const& instruction : resourceInstruction)
|
for (auto const& instruction : resourceInstruction)
|
||||||
{
|
{
|
||||||
// If the resource that the new node is requesting for exists, allow the graph to reference it
|
// If the resource that the new node is requesting for exists, allow the graph to reference it
|
||||||
if (graphResources.contains(instruction.resourceName))
|
if (renderGraphStorage->graphResources->contains(instruction.resourceName))
|
||||||
{
|
{
|
||||||
descInitParams.push_back(
|
descInitParams.push_back(
|
||||||
{
|
{
|
||||||
.resourceHdl = graphResources.at(instruction.resourceName),
|
.resourceHdl = renderGraphStorage->graphResources->at(instruction.resourceName),
|
||||||
.dontClearOnLoad = false,
|
.dontClearOnLoad = instruction.dontClearOnLoad,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -456,7 +464,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources));
|
nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
|
||||||
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
||||||
return nodes.at(nodeIndexing[nodeName]);
|
return nodes.at(nodeIndexing[nodeName]);
|
||||||
}
|
}
|
||||||
|
@ -476,12 +484,31 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::Generate(void) noexcept
|
void SHRenderGraph::Generate(void) noexcept
|
||||||
{
|
{
|
||||||
|
CheckForNodeComputes();
|
||||||
ConfigureAttachmentDescriptions();
|
ConfigureAttachmentDescriptions();
|
||||||
ConfigureSubpasses();
|
ConfigureSubpasses();
|
||||||
ConfigureRenderpasses();
|
ConfigureRenderpasses();
|
||||||
ConfigureFramebuffers();
|
ConfigureFramebuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function goes through all renderpasses and checks for existence of
|
||||||
|
node computes. If they exist, adds dummy subpasses to transition resources
|
||||||
|
into general.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraph::CheckForNodeComputes(void) noexcept
|
||||||
|
{
|
||||||
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
node->AddDummySubpassIfNeeded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a
|
// TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a
|
||||||
// better way to manage these
|
// better way to manage these
|
||||||
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||||
|
@ -501,7 +528,7 @@ namespace SHADE
|
||||||
void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept
|
void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||||
{
|
{
|
||||||
// resize resources
|
// resize resources
|
||||||
for (auto& [name, resource]: graphResources)
|
for (auto& [name, resource] : *renderGraphStorage->graphResources)
|
||||||
resource->HandleResize(newWidth, newHeight);
|
resource->HandleResize(newWidth, newHeight);
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
|
@ -521,9 +548,9 @@ namespace SHADE
|
||||||
|
|
||||||
Handle<SHRenderGraphResource> SHRenderGraph::GetRenderGraphResource(std::string const& resourceName) const noexcept
|
Handle<SHRenderGraphResource> SHRenderGraph::GetRenderGraphResource(std::string const& resourceName) const noexcept
|
||||||
{
|
{
|
||||||
if (graphResources.contains(resourceName))
|
if (renderGraphStorage->graphResources->contains(resourceName))
|
||||||
{
|
{
|
||||||
return graphResources.at(resourceName);
|
return renderGraphStorage->graphResources->at(resourceName);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@ namespace SHADE
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHRenderGraphNode;
|
class SHRenderGraphNode;
|
||||||
class SHGraphicsGlobalData;
|
class SHGraphicsGlobalData;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
class SHRenderGraphStorage;
|
||||||
|
|
||||||
class SH_API SHRenderGraph
|
class SH_API SHRenderGraph
|
||||||
{
|
{
|
||||||
|
@ -56,10 +57,8 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
|
||||||
|
|
||||||
//! swapchain used for querying image count
|
Handle<SHRenderGraphStorage> renderGraphStorage;
|
||||||
Handle<SHVkSwapchain> swapchainHdl;
|
|
||||||
|
|
||||||
//! For indexing render graph node container
|
//! For indexing render graph node container
|
||||||
std::map<std::string, uint32_t> nodeIndexing;
|
std::map<std::string, uint32_t> nodeIndexing;
|
||||||
|
@ -67,9 +66,6 @@ namespace SHADE
|
||||||
//! Render graph nodes
|
//! Render graph nodes
|
||||||
std::vector<Handle<SHRenderGraphNode>> nodes;
|
std::vector<Handle<SHRenderGraphNode>> nodes;
|
||||||
|
|
||||||
//! Resources that exist for the entire render graph
|
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> graphResources;
|
|
||||||
|
|
||||||
//! Resource library for graph handles
|
//! Resource library for graph handles
|
||||||
std::shared_ptr<SHResourceHub> resourceManager;
|
std::shared_ptr<SHResourceHub> resourceManager;
|
||||||
|
|
||||||
|
@ -85,13 +81,14 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
|
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept;
|
||||||
void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
|
void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
|
||||||
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
|
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
|
||||||
|
|
||||||
void Generate (void) noexcept;
|
void Generate (void) noexcept;
|
||||||
|
void CheckForNodeComputes (void) noexcept;
|
||||||
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
void FinaliseBatch (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||||
#include "SHRenderGraphResource.h"
|
#include "SHRenderGraphResource.h"
|
||||||
#include "SHSubpass.h"
|
#include "SHSubpass.h"
|
||||||
|
#include "SHRenderGraphStorage.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -21,7 +24,7 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraphNode::CreateRenderpass(void) noexcept
|
void SHRenderGraphNode::CreateRenderpass(void) noexcept
|
||||||
{
|
{
|
||||||
renderpass = logicalDeviceHdl->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -53,7 +56,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
framebuffers[i] = logicalDeviceHdl->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,9 +82,18 @@ namespace SHADE
|
||||||
fbHeight = attResources[j]->height;
|
fbHeight = attResources[j]->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& subpass : subpasses)
|
||||||
|
{
|
||||||
|
subpass->HandleResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& nodeCompute : nodeComputes)
|
||||||
|
{
|
||||||
|
nodeCompute->HandleResize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -104,8 +116,8 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr<SHResourceHub> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
SHRenderGraphNode::SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept
|
||||||
: logicalDeviceHdl{ logicalDevice }
|
: graphStorage{ renderGraphStorage}
|
||||||
, renderpass{}
|
, renderpass{}
|
||||||
, framebuffers{}
|
, framebuffers{}
|
||||||
, prereqNodes{ std::move(predecessors) }
|
, prereqNodes{ std::move(predecessors) }
|
||||||
|
@ -115,11 +127,10 @@ namespace SHADE
|
||||||
, subpasses{}
|
, subpasses{}
|
||||||
, executed{ false }
|
, executed{ false }
|
||||||
, configured{ false }
|
, configured{ false }
|
||||||
, resourceManager{ rm }
|
, nodeComputes{}
|
||||||
, ptrToResources{ resources }
|
|
||||||
{
|
{
|
||||||
// pipeline library initialization
|
// pipeline library initialization
|
||||||
pipelineLibrary.Init(logicalDeviceHdl);
|
pipelineLibrary.Init(graphStorage->logicalDevice);
|
||||||
|
|
||||||
// Store all the handles to resources
|
// Store all the handles to resources
|
||||||
attResources.reserve (attDescInitParams.size());
|
attResources.reserve (attDescInitParams.size());
|
||||||
|
@ -155,15 +166,14 @@ namespace SHADE
|
||||||
if (!containsSwapchainImage)
|
if (!containsSwapchainImage)
|
||||||
framebuffers.resize(1);
|
framebuffers.resize(1);
|
||||||
else
|
else
|
||||||
framebuffers.resize(swapchain->GetNumImages());
|
framebuffers.resize(graphStorage->swapchain->GetNumImages());
|
||||||
|
|
||||||
// At this point, we could configure framebuffers if we had the renderpass object but we don't so their creation has to be
|
// At this point, we could configure framebuffers if we had the renderpass object but we don't so their creation has to be
|
||||||
// deferred to when renderpasses are also created.
|
// deferred to when renderpasses are also created.
|
||||||
}
|
}
|
||||||
|
|
||||||
SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept
|
SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept
|
||||||
: resourceManager{ std::move (rhs.resourceManager) }
|
: graphStorage{ rhs.graphStorage}
|
||||||
, logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
|
||||||
, renderpass{ rhs.renderpass }
|
, renderpass{ rhs.renderpass }
|
||||||
, framebuffers{ std::move(rhs.framebuffers) }
|
, framebuffers{ std::move(rhs.framebuffers) }
|
||||||
, prereqNodes{ std::move(rhs.prereqNodes) }
|
, prereqNodes{ std::move(rhs.prereqNodes) }
|
||||||
|
@ -174,11 +184,11 @@ namespace SHADE
|
||||||
, subpassIndexing{ std::move(rhs.subpassIndexing) }
|
, subpassIndexing{ std::move(rhs.subpassIndexing) }
|
||||||
, configured{ rhs.configured }
|
, configured{ rhs.configured }
|
||||||
, executed{ rhs.executed }
|
, executed{ rhs.executed }
|
||||||
, ptrToResources{ rhs.ptrToResources }
|
|
||||||
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
||||||
, batcher{ std::move(rhs.batcher) }
|
, batcher{ std::move(rhs.batcher) }
|
||||||
, spDescs{ std::move(rhs.spDescs) }
|
, spDescs{ std::move(rhs.spDescs) }
|
||||||
, spDeps{ std::move(rhs.spDeps) }
|
, spDeps{ std::move(rhs.spDeps) }
|
||||||
|
, nodeComputes{ std::move(rhs.nodeComputes) }
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
@ -189,8 +199,7 @@ namespace SHADE
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
resourceManager = std::move(rhs.resourceManager);
|
graphStorage = rhs.graphStorage;
|
||||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
|
||||||
renderpass = rhs.renderpass;
|
renderpass = rhs.renderpass;
|
||||||
framebuffers = std::move(rhs.framebuffers);
|
framebuffers = std::move(rhs.framebuffers);
|
||||||
prereqNodes = std::move(rhs.prereqNodes);
|
prereqNodes = std::move(rhs.prereqNodes);
|
||||||
|
@ -199,11 +208,11 @@ namespace SHADE
|
||||||
subpasses = std::move(rhs.subpasses);
|
subpasses = std::move(rhs.subpasses);
|
||||||
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping);
|
||||||
subpassIndexing = std::move(rhs.subpassIndexing);
|
subpassIndexing = std::move(rhs.subpassIndexing);
|
||||||
ptrToResources = std::move(rhs.ptrToResources);
|
|
||||||
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
||||||
batcher = std::move(rhs.batcher);
|
batcher = std::move(rhs.batcher);
|
||||||
spDescs = std::move(rhs.spDescs);
|
spDescs = std::move(rhs.spDescs);
|
||||||
spDeps = std::move(rhs.spDeps);
|
spDeps = std::move(rhs.spDeps);
|
||||||
|
nodeComputes = std::move(rhs.nodeComputes);
|
||||||
|
|
||||||
|
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
@ -235,10 +244,10 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add subpass to container and create mapping for it
|
// Add subpass to container and create mapping for it
|
||||||
subpasses.emplace_back(resourceManager->Create<SHSubpass>(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
subpasses.emplace_back(graphStorage->resourceManager->Create<SHSubpass>(graphStorage, GetHandle(), static_cast<uint32_t>(subpasses.size()), &resourceAttachmentMapping));
|
||||||
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
||||||
Handle<SHSubpass> subpass = subpasses.back();
|
Handle<SHSubpass> subpass = subpasses.back();
|
||||||
subpass->Init(*resourceManager);
|
subpass->Init(*graphStorage->resourceManager);
|
||||||
|
|
||||||
// Register the SuperBatch
|
// Register the SuperBatch
|
||||||
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
|
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
|
||||||
|
@ -246,21 +255,84 @@ namespace SHADE
|
||||||
return subpass;
|
return subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, float numWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
|
{
|
||||||
|
// Look for the required resources in the graph
|
||||||
|
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
||||||
|
nodeComputeResources.reserve(resources.size());
|
||||||
|
|
||||||
|
for (auto& resourceName : resources)
|
||||||
|
{
|
||||||
|
auto resource = graphStorage->graphResources->at(resourceName);
|
||||||
|
nodeComputeResources.push_back(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the subpass compute with the resources
|
||||||
|
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources));
|
||||||
|
nodeComputes.push_back(nodeCompute);
|
||||||
|
|
||||||
|
return nodeCompute;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function checks all node computes and adds a subpass to transition
|
||||||
|
all needed resources to general.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::AddDummySubpassIfNeeded(void) noexcept
|
||||||
|
{
|
||||||
|
if (!nodeComputes.empty())
|
||||||
|
{
|
||||||
|
// we save the resource names involved
|
||||||
|
std::unordered_set<std::string> resourcesInvolved;
|
||||||
|
for (auto& compute : nodeComputes)
|
||||||
|
{
|
||||||
|
for (auto& resource : compute->resources)
|
||||||
|
{
|
||||||
|
resourcesInvolved.emplace(resource->GetName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert them all for a subpass to transition them. This subpass is the last subpass
|
||||||
|
auto dummySubpass = AddSubpass("dummy");
|
||||||
|
for (auto& resource : resourcesInvolved)
|
||||||
|
{
|
||||||
|
dummySubpass->AddGeneralInput(resource);
|
||||||
|
|
||||||
|
if (SHVkUtil::IsDepthStencilAttachment(graphStorage->graphResources->at(resource)->GetResourceFormat()))
|
||||||
|
dummySubpass->AddGeneralDepthOutput(resource);
|
||||||
|
else
|
||||||
|
dummySubpass->AddGeneralColorOutput(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
frameIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
||||||
commandBuffer->BeginRenderpass(renderpass, framebuffers[frameIndex]);
|
commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
||||||
{
|
{
|
||||||
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
||||||
|
|
||||||
// Go to next subpass if not last subpass
|
// Go to next subpass if not last subpass
|
||||||
if (i != subpasses.size() - 1)
|
if (i != static_cast<uint32_t>(subpasses.size()) - 1u)
|
||||||
commandBuffer->NextSubpass();
|
commandBuffer->NextSubpass();
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuffer->EndRenderpass();
|
commandBuffer->EndRenderpass();
|
||||||
|
|
||||||
|
|
||||||
|
// Execute all subpass computes
|
||||||
|
for (auto& sbCompute : nodeComputes)
|
||||||
|
{
|
||||||
|
sbCompute->Execute(commandBuffer, frameIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
||||||
|
@ -273,10 +345,10 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetDrawPipline(vsFsPair);
|
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetGraphicsPipeline(vsFsPair);
|
||||||
if (!pipeline)
|
if (!pipeline)
|
||||||
{
|
{
|
||||||
pipeline = pipelineLibrary.CreateDrawPipeline
|
pipeline = pipelineLibrary.CreateGraphicsPipelines
|
||||||
(
|
(
|
||||||
vsFsPair,
|
vsFsPair,
|
||||||
renderpass,
|
renderpass,
|
||||||
|
@ -289,7 +361,7 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
{
|
{
|
||||||
batcher.FinaliseBatches(logicalDeviceHdl, descPool, frameIndex);
|
batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
|
@ -19,6 +19,9 @@ namespace SHADE
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkRenderpass;
|
class SHVkRenderpass;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
|
class SHGraphicsGlobalData;
|
||||||
|
class SHRenderGraphStorage;
|
||||||
|
class SHRenderGraphNodeCompute;
|
||||||
|
|
||||||
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
|
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
|
||||||
{
|
{
|
||||||
|
@ -26,10 +29,9 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
std::shared_ptr<SHResourceHub> resourceManager;
|
|
||||||
|
|
||||||
//! For Vulkan object creation
|
//! For Vulkan object creation
|
||||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
//Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||||
|
Handle<SHRenderGraphStorage> graphStorage;
|
||||||
|
|
||||||
//! Each node will have a renderpass and each renderpass will have its own subpasses.
|
//! Each node will have a renderpass and each renderpass will have its own subpasses.
|
||||||
//! These subpasses will execute sequentially.
|
//! These subpasses will execute sequentially.
|
||||||
|
@ -63,12 +65,13 @@ namespace SHADE
|
||||||
//! For indexing subpasses
|
//! For indexing subpasses
|
||||||
std::map<std::string, uint32_t> subpassIndexing;
|
std::map<std::string, uint32_t> subpassIndexing;
|
||||||
|
|
||||||
//! Pointer to resources in the render graph (for getting handle IDs)
|
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
|
||||||
|
|
||||||
//! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass
|
//! Every renderpass will require a pipeline library that will contain pipelines compatible with this renderpass
|
||||||
SHPipelineLibrary pipelineLibrary;
|
SHPipelineLibrary pipelineLibrary;
|
||||||
|
|
||||||
|
//! Sometimes we want the subpass to do something to the images instead
|
||||||
|
//! of drawing objects on the image (i.e. compute).
|
||||||
|
std::vector<Handle<SHRenderGraphNodeCompute>> nodeComputes;
|
||||||
|
|
||||||
//! Whether or not the node has finished execution
|
//! Whether or not the node has finished execution
|
||||||
bool executed;
|
bool executed;
|
||||||
|
|
||||||
|
@ -77,6 +80,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHBatcher batcher;
|
SHBatcher batcher;
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -88,7 +92,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraphNode(std::shared_ptr<SHResourceHub> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
|
SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept;
|
||||||
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
||||||
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
||||||
|
|
||||||
|
@ -96,6 +100,9 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
||||||
|
Handle<SHRenderGraphNodeCompute> AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, float numWorkGroupScale = 1.0f) noexcept;
|
||||||
|
void AddDummySubpassIfNeeded (void) noexcept;
|
||||||
|
|
||||||
// TODO: RemoveSubpass()
|
// TODO: RemoveSubpass()
|
||||||
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHRenderGraphNodeCompute.h"
|
||||||
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
||||||
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||||
|
#include "SHRenderGraphStorage.h"
|
||||||
|
#include "SHRenderGraphResource.h"
|
||||||
|
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
|
: computePipeline{}
|
||||||
|
, pipelineLayout{}
|
||||||
|
, resources{}
|
||||||
|
, groupSizeX{0}
|
||||||
|
, groupSizeY{0}
|
||||||
|
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
|
||||||
|
{
|
||||||
|
SHPipelineLayoutParams pipelineLayoutParams
|
||||||
|
{
|
||||||
|
.shaderModules = {computeShaderModule},
|
||||||
|
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create pipeline layout from parameters
|
||||||
|
pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams);
|
||||||
|
|
||||||
|
// Create the compute pipeline
|
||||||
|
computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout);
|
||||||
|
|
||||||
|
// and construct it
|
||||||
|
computePipeline->ConstructPipeline();
|
||||||
|
|
||||||
|
// save the resources
|
||||||
|
resources = std::move (subpassComputeResources);
|
||||||
|
|
||||||
|
//Get the descriptor set layouts required to allocate. We only want the ones for allocate because
|
||||||
|
//global descriptors are already bound in the main system.
|
||||||
|
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate();
|
||||||
|
|
||||||
|
//Variable counts for the descriptor sets (all should be 1).
|
||||||
|
std::vector<uint32_t> variableCounts{ static_cast<uint32_t>(layouts.size()) };
|
||||||
|
std::fill(variableCounts.begin(), variableCounts.end(), 0);
|
||||||
|
|
||||||
|
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
||||||
|
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||||
|
{
|
||||||
|
descSetGroups[i] = graphStorage->descriptorPool->Allocate(layouts, variableCounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HandleResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::Execute(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
// bind the compute pipeline
|
||||||
|
cmdBuffer->BindPipeline(computePipeline);
|
||||||
|
|
||||||
|
// bind descriptor sets
|
||||||
|
cmdBuffer->BindDescriptorSet(descSetGroups[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {});
|
||||||
|
|
||||||
|
// dispatch compute
|
||||||
|
cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1);
|
||||||
|
|
||||||
|
// TODO: barrier
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::HandleResize(void) noexcept
|
||||||
|
{
|
||||||
|
// Get the layout for the render graph resource. We can index it this way because the container returned is a container of layouts that includes the global ones
|
||||||
|
auto pipelineDescSetLayouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE];
|
||||||
|
|
||||||
|
// everything below here needs resizing
|
||||||
|
for (uint32_t frameIndex = 0; frameIndex < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++frameIndex)
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
// loop through bindings and write descriptor sets
|
||||||
|
for (auto& binding : pipelineDescSetLayouts->GetBindings())
|
||||||
|
{
|
||||||
|
uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0;
|
||||||
|
|
||||||
|
SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle<SHVkSampler>{}, vk::ImageLayout::eGeneral);
|
||||||
|
descSetGroups[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 });
|
||||||
|
descSetGroups[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the group size from the max width and height
|
||||||
|
uint32_t maxWidth = 0, maxHeight = 0;
|
||||||
|
for (auto& resource : resources)
|
||||||
|
{
|
||||||
|
maxWidth = std::max(resource->GetWidth(), maxWidth);
|
||||||
|
maxHeight = std::max(resource->GetHeight(), maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupSizeX = maxWidth / workGroupSizeX;
|
||||||
|
groupSizeY = maxHeight / workGroupSizeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHVkPipeline;
|
||||||
|
class SHVkDescriptorSetGroup;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
class SHVkPipelineLayout;
|
||||||
|
class SHRenderGraphStorage;
|
||||||
|
class SHRenderGraphResource;
|
||||||
|
class SHVkShaderModule;
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
|
||||||
|
class SHRenderGraphNodeCompute
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static constexpr uint32_t workGroupSizeX = 16;
|
||||||
|
static constexpr uint32_t workGroupSizeY = 16;
|
||||||
|
|
||||||
|
//! To run the dispatch command
|
||||||
|
Handle<SHVkPipeline> computePipeline;
|
||||||
|
|
||||||
|
//! Pipeline layout for the pipeline creation
|
||||||
|
Handle<SHVkPipelineLayout> pipelineLayout;
|
||||||
|
|
||||||
|
//! Descriptor set group to hold the images for reading (STORAGE_IMAGE)
|
||||||
|
std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS> descSetGroups;
|
||||||
|
|
||||||
|
//! vector of resources needed by the subpass compute
|
||||||
|
std::vector<Handle<SHRenderGraphResource>> resources;
|
||||||
|
|
||||||
|
//! X dimension work group size. Should scale with resource size.
|
||||||
|
uint32_t groupSizeX;
|
||||||
|
|
||||||
|
//! Y dimension work group size
|
||||||
|
uint32_t groupSizeY;
|
||||||
|
|
||||||
|
float numWorkGroupScale;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, float inNumWorkGroupScale = 1.0f) noexcept;
|
||||||
|
|
||||||
|
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
void HandleResize (void) noexcept;
|
||||||
|
|
||||||
|
friend class SHRenderGraph;
|
||||||
|
friend class SHRenderGraphNode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Graphics/Images/SHVkImageView.h"
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
#include "SHRenderGraphStorage.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -45,9 +46,8 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
|
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
|
||||||
: logicalDevice {logicalDevice}
|
: graphStorage{renderGraphStorage}
|
||||||
, swapchain{ swapchain }
|
|
||||||
, resourceTypeFlags{ }
|
, resourceTypeFlags{ }
|
||||||
, resourceFormat{ format }
|
, resourceFormat{ format }
|
||||||
, images{}
|
, images{}
|
||||||
|
@ -66,7 +66,7 @@ namespace SHADE
|
||||||
SHImageViewDetails viewDetails
|
SHImageViewDetails viewDetails
|
||||||
{
|
{
|
||||||
.viewType = vk::ImageViewType::e2D,
|
.viewType = vk::ImageViewType::e2D,
|
||||||
.format = swapchain->GetSurfaceFormatKHR().format,
|
.format = graphStorage->swapchain->GetSurfaceFormatKHR().format,
|
||||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.mipLevelCount = 1,
|
.mipLevelCount = 1,
|
||||||
|
@ -75,13 +75,13 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// We want an image handle for every swapchain image
|
// We want an image handle for every swapchain image
|
||||||
images.resize(swapchain->GetNumImages());
|
images.resize(graphStorage->swapchain->GetNumImages());
|
||||||
imageViews.resize(swapchain->GetNumImages());
|
imageViews.resize(graphStorage->swapchain->GetNumImages());
|
||||||
|
|
||||||
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
|
for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i)
|
||||||
{
|
{
|
||||||
images[i] = swapchain->GetSwapchainImage(i);
|
images[i] = graphStorage->swapchain->GetSwapchainImage(i);
|
||||||
imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails);
|
imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // if swapchain image resource
|
else // if swapchain image resource
|
||||||
|
@ -117,6 +117,9 @@ namespace SHADE
|
||||||
usage |= vk::ImageUsageFlagBits::eInputAttachment;
|
usage |= vk::ImageUsageFlagBits::eInputAttachment;
|
||||||
usage |= vk::ImageUsageFlagBits::eSampled;
|
usage |= vk::ImageUsageFlagBits::eSampled;
|
||||||
break;
|
break;
|
||||||
|
case SH_ATT_DESC_TYPE_FLAGS::STORAGE:
|
||||||
|
usage |= vk::ImageUsageFlagBits::eStorage;
|
||||||
|
break;
|
||||||
case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT:
|
case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT:
|
||||||
{
|
{
|
||||||
SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. ");
|
SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. ");
|
||||||
|
@ -126,7 +129,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// The resource is not a swapchain image, just use the first slot of the vector
|
// The resource is not a swapchain image, just use the first slot of the vector
|
||||||
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
|
images.push_back(graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
|
||||||
|
|
||||||
// prepare image view details
|
// prepare image view details
|
||||||
SHImageViewDetails viewDetails
|
SHImageViewDetails viewDetails
|
||||||
|
@ -141,7 +144,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// just 1 image view created
|
// just 1 image view created
|
||||||
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
|
imageViews.push_back(images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +169,7 @@ namespace SHADE
|
||||||
, height{ rhs.height }
|
, height{ rhs.height }
|
||||||
, mipLevels{ rhs.mipLevels }
|
, mipLevels{ rhs.mipLevels }
|
||||||
, imageAspectFlags{ rhs.imageAspectFlags }
|
, imageAspectFlags{ rhs.imageAspectFlags }
|
||||||
, swapchain {rhs.swapchain}
|
, graphStorage{rhs.graphStorage}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -198,7 +201,7 @@ namespace SHADE
|
||||||
height = rhs.height;
|
height = rhs.height;
|
||||||
mipLevels = rhs.mipLevels;
|
mipLevels = rhs.mipLevels;
|
||||||
imageAspectFlags = rhs.imageAspectFlags;
|
imageAspectFlags = rhs.imageAspectFlags;
|
||||||
swapchain = rhs.swapchain;
|
graphStorage = rhs.graphStorage;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +250,7 @@ namespace SHADE
|
||||||
SHImageViewDetails viewDetails
|
SHImageViewDetails viewDetails
|
||||||
{
|
{
|
||||||
.viewType = vk::ImageViewType::e2D,
|
.viewType = vk::ImageViewType::e2D,
|
||||||
.format = swapchain->GetSurfaceFormatKHR().format,
|
.format = graphStorage->swapchain->GetSurfaceFormatKHR().format,
|
||||||
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.mipLevelCount = 1,
|
.mipLevelCount = 1,
|
||||||
|
@ -255,9 +258,9 @@ namespace SHADE
|
||||||
.layerCount = 1,
|
.layerCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
|
for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i)
|
||||||
{
|
{
|
||||||
images[i] = swapchain->GetSwapchainImage(i);
|
images[i] = graphStorage->swapchain->GetSwapchainImage(i);
|
||||||
imageViews[i]->ViewNewImage(images[i], viewDetails);
|
imageViews[i]->ViewNewImage(images[i], viewDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,6 +311,7 @@ namespace SHADE
|
||||||
return resourceFormat;
|
return resourceFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SHRenderGraphResource::GetWidth(void) const noexcept
|
uint32_t SHRenderGraphResource::GetWidth(void) const noexcept
|
||||||
{
|
{
|
||||||
return width;
|
return width;
|
||||||
|
@ -323,4 +327,19 @@ namespace SHADE
|
||||||
return imageViews [index];
|
return imageViews [index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkImage> SHRenderGraphResource::GetImage(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept
|
||||||
|
{
|
||||||
|
return images[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SHRenderGraphResource::GetMipLevels(void) const noexcept
|
||||||
|
{
|
||||||
|
return mipLevels;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHRenderGraphResource::GetName(void) const noexcept
|
||||||
|
{
|
||||||
|
return resourceName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@ namespace SHADE
|
||||||
class SHVkSwapchain;
|
class SHVkSwapchain;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkBuffer;
|
class SHVkBuffer;
|
||||||
|
class SHRenderGraphStorage;
|
||||||
|
|
||||||
static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0;
|
static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0;
|
||||||
|
|
||||||
|
@ -24,11 +25,8 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// for creation/recreation
|
//! Storage from the render graph
|
||||||
Handle<SHVkLogicalDevice> logicalDevice;
|
Handle<SHRenderGraphStorage> graphStorage;
|
||||||
|
|
||||||
// for creation/recreation
|
|
||||||
Handle<SHVkSwapchain> swapchain;
|
|
||||||
|
|
||||||
//! Name of the resource
|
//! Name of the resource
|
||||||
std::string resourceName;
|
std::string resourceName;
|
||||||
|
@ -69,7 +67,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
|
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
|
||||||
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
||||||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||||
~SHRenderGraphResource(void) noexcept;
|
~SHRenderGraphResource(void) noexcept;
|
||||||
|
@ -88,8 +86,13 @@ namespace SHADE
|
||||||
uint32_t GetWidth (void) const noexcept;
|
uint32_t GetWidth (void) const noexcept;
|
||||||
uint32_t GetHeight (void) const noexcept;
|
uint32_t GetHeight (void) const noexcept;
|
||||||
Handle<SHVkImageView> GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
|
Handle<SHVkImageView> GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
|
||||||
|
Handle<SHVkImage> GetImage (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
|
||||||
|
uint8_t GetMipLevels (void) const noexcept;
|
||||||
|
std::string GetName (void) const noexcept;
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
|
friend class SHSubpass;
|
||||||
|
friend class SHRenderGraphNodeCompute;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
class SHVkSwapchain;
|
||||||
|
class SHGraphicsGlobalData;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
class SHRenderGraphResource;
|
||||||
|
|
||||||
|
class SHRenderGraphStorage
|
||||||
|
{
|
||||||
|
//! Logical device for creation of vulkan objects
|
||||||
|
Handle<SHVkLogicalDevice> logicalDevice;
|
||||||
|
|
||||||
|
//! swapchain handle
|
||||||
|
Handle<SHVkSwapchain> swapchain;
|
||||||
|
|
||||||
|
//! Resource manager for creation of objects
|
||||||
|
std::shared_ptr<SHResourceHub> resourceManager;
|
||||||
|
|
||||||
|
//! Descriptor pool for the descriptor sets to be created in the subpasses
|
||||||
|
Handle<SHVkDescriptorPool> descriptorPool;
|
||||||
|
|
||||||
|
//! For accessing resources anywhere in the graph
|
||||||
|
Handle<std::unordered_map<std::string, Handle<SHRenderGraphResource>>> graphResources;
|
||||||
|
|
||||||
|
//SHRenderGraphStorage(void) noexcept;
|
||||||
|
//SHRenderGraphStorage(SHRenderGraphStorage&& rhs) noexcept;
|
||||||
|
//SHRenderGraphStorage& operator=(SHRenderGraphStorage&& rhs) noexcept;
|
||||||
|
|
||||||
|
friend class SHRenderGraph;
|
||||||
|
friend class SHRenderGraphNode;
|
||||||
|
friend class SHSubpass;
|
||||||
|
friend class SHRenderGraphResource;
|
||||||
|
friend class SHRenderGraphNodeCompute;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,13 @@
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "SHRenderGraphNode.h"
|
#include "SHRenderGraphNode.h"
|
||||||
#include "SHRenderGraphResource.h"
|
#include "SHRenderGraphResource.h"
|
||||||
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
|
#include "SHRenderGraphNode.h"
|
||||||
|
#include "SHRenderGraphStorage.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "SHRenderGraphResource.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -23,15 +30,16 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHSubpass::SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
SHSubpass::SHSubpass(Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept
|
||||||
: resourceAttachmentMapping{ mapping }
|
: resourceAttachmentMapping{ mapping }
|
||||||
, ptrToResources{ resources }
|
|
||||||
, parentNode{ parent }
|
, parentNode{ parent }
|
||||||
, subpassIndex{ index }
|
, subpassIndex{ index }
|
||||||
, superBatch{}
|
, superBatch{}
|
||||||
, colorReferences{}
|
, colorReferences{}
|
||||||
, depthReferences{}
|
, depthReferences{}
|
||||||
, inputReferences{}
|
, inputReferences{}
|
||||||
|
, graphStorage{ renderGraphStorage }
|
||||||
|
, inputImageDescriptors {SHGraphicsConstants::NUM_FRAME_BUFFERS}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +62,14 @@ namespace SHADE
|
||||||
, depthReferences{ std::move(rhs.depthReferences) }
|
, depthReferences{ std::move(rhs.depthReferences) }
|
||||||
, inputReferences{ std::move(rhs.inputReferences) }
|
, inputReferences{ std::move(rhs.inputReferences) }
|
||||||
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
|
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
|
||||||
, ptrToResources{ rhs.ptrToResources }
|
|
||||||
, descriptorSetLayout{ rhs.descriptorSetLayout }
|
, descriptorSetLayout{ rhs.descriptorSetLayout }
|
||||||
, exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) }
|
, exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) }
|
||||||
|
, graphStorage{ rhs.graphStorage }
|
||||||
|
, inputNames{ std::move(rhs.inputNames) }
|
||||||
|
, inputImageDescriptors{ std::move(rhs.inputImageDescriptors) }
|
||||||
|
, inputDescriptorLayout{ rhs.inputDescriptorLayout }
|
||||||
|
, inputSamplers{ rhs.inputSamplers }
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -84,9 +97,13 @@ namespace SHADE
|
||||||
depthReferences = std::move(rhs.depthReferences);
|
depthReferences = std::move(rhs.depthReferences);
|
||||||
inputReferences = std::move(rhs.inputReferences);
|
inputReferences = std::move(rhs.inputReferences);
|
||||||
resourceAttachmentMapping = rhs.resourceAttachmentMapping;
|
resourceAttachmentMapping = rhs.resourceAttachmentMapping;
|
||||||
ptrToResources = rhs.ptrToResources;
|
|
||||||
descriptorSetLayout = rhs.descriptorSetLayout;
|
descriptorSetLayout = rhs.descriptorSetLayout;
|
||||||
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
|
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
|
||||||
|
graphStorage = rhs.graphStorage;
|
||||||
|
inputNames = std::move(rhs.inputNames);
|
||||||
|
inputImageDescriptors = std::move(rhs.inputImageDescriptors);
|
||||||
|
inputDescriptorLayout = rhs.inputDescriptorLayout;
|
||||||
|
inputSamplers = rhs.inputSamplers;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +122,12 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept
|
void SHSubpass::AddColorOutput(std::string resourceToReference) noexcept
|
||||||
{
|
{
|
||||||
colorReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal });
|
colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eColorAttachmentOptimal });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::AddGeneralColorOutput(std::string resourceToReference) noexcept
|
||||||
|
{
|
||||||
|
colorReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral });
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -142,7 +164,13 @@ namespace SHADE
|
||||||
//Invalid
|
//Invalid
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
depthReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), imageLayout });
|
depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), imageLayout });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::AddGeneralDepthOutput(std::string resourceToReference) noexcept
|
||||||
|
{
|
||||||
|
depthReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -159,7 +187,14 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHSubpass::AddInput(std::string resourceToReference) noexcept
|
void SHSubpass::AddInput(std::string resourceToReference) noexcept
|
||||||
{
|
{
|
||||||
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
||||||
|
|
||||||
|
inputNames.push_back(resourceToReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::AddGeneralInput(std::string resourceToReference) noexcept
|
||||||
|
{
|
||||||
|
inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
|
@ -175,6 +210,12 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
drawCall(commandBuffer);
|
drawCall(commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::HandleResize(void) noexcept
|
||||||
|
{
|
||||||
|
UpdateWriteDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
void SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
||||||
|
@ -188,6 +229,152 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSubpass::CreateInputDescriptors(void) noexcept
|
||||||
|
{
|
||||||
|
if (inputNames.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<SHVkDescriptorSetLayout::Binding> bindings{};
|
||||||
|
|
||||||
|
for (auto& input : inputReferences)
|
||||||
|
{
|
||||||
|
SHVkDescriptorSetLayout::Binding newBinding
|
||||||
|
{
|
||||||
|
.Type = (input.layout == vk::ImageLayout::eShaderReadOnlyOptimal) ? vk::DescriptorType::eInputAttachment : vk::DescriptorType::eStorageImage,
|
||||||
|
.Stage = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
.BindPoint = static_cast<uint32_t>(bindings.size()),
|
||||||
|
.DescriptorCount = 1,
|
||||||
|
.flags = {},
|
||||||
|
};
|
||||||
|
|
||||||
|
bindings.push_back(newBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We build a new descriptor set layout to store our images
|
||||||
|
inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings);
|
||||||
|
|
||||||
|
// we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle.
|
||||||
|
for (uint32_t i = 0; i < bindings.size(); ++i)
|
||||||
|
{
|
||||||
|
if (bindings[i].Type == vk::DescriptorType::eInputAttachment)
|
||||||
|
{
|
||||||
|
auto newSampler = graphStorage->logicalDevice->CreateSampler(SHVkSamplerParams
|
||||||
|
{
|
||||||
|
.minFilter = vk::Filter::eLinear,
|
||||||
|
.magFilter = vk::Filter::eLinear,
|
||||||
|
.addressMode = vk::SamplerAddressMode::eRepeat,
|
||||||
|
.mipmapMode = vk::SamplerMipmapMode::eLinear,
|
||||||
|
.minLod = -1000,
|
||||||
|
.maxLod = 1000
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inputSamplers.push_back(newSampler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputSamplers.push_back({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//// maybe do this in handle resize?
|
||||||
|
//UpdateWriteDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSubpass::UpdateWriteDescriptors(void) noexcept
|
||||||
|
{
|
||||||
|
if (inputNames.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto const& bindings = inputDescriptorLayout->GetBindings();
|
||||||
|
|
||||||
|
std::vector<uint32_t> variableCounts{ static_cast<uint32_t>(bindings.size()) };
|
||||||
|
std::fill (variableCounts.begin(), variableCounts.end(), 0u);
|
||||||
|
|
||||||
|
|
||||||
|
// For every frame's descriptor set
|
||||||
|
for (auto& group : inputImageDescriptors)
|
||||||
|
{
|
||||||
|
if (group)
|
||||||
|
group.Free();
|
||||||
|
|
||||||
|
group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts);
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (auto& binding : bindings)
|
||||||
|
{
|
||||||
|
// get the resource
|
||||||
|
auto resource = graphStorage->graphResources->at(inputNames[binding.BindPoint]);
|
||||||
|
|
||||||
|
// If resource is swapchain image, get the correct image, if not just get 0.
|
||||||
|
uint32_t viewIndex = (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
||||||
|
|
||||||
|
// layout is GENERAL if image is meant to be used as storage image, if not use SHADER_READ_ONLY_OPTINAL
|
||||||
|
vk::ImageLayout descriptorLayout = (binding.Type == vk::DescriptorType::eStorageImage) ? vk::ImageLayout::eGeneral : vk::ImageLayout::eShaderReadOnlyOptimal;
|
||||||
|
|
||||||
|
// Update descriptor sets
|
||||||
|
auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout);
|
||||||
|
group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1});
|
||||||
|
group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHSubpass::InitComputeBarriers(void) noexcept
|
||||||
|
//{
|
||||||
|
// std::unordered_set <uint64_t> handleBarriers{};
|
||||||
|
|
||||||
|
// // we will have swapchainNumImages vectors of vector of barriers
|
||||||
|
// subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages());
|
||||||
|
|
||||||
|
// for (auto sbCompute : subpassComputes)
|
||||||
|
// {
|
||||||
|
// // for every resource the subpass compute is using
|
||||||
|
// for (auto resource : sbCompute->resources)
|
||||||
|
// {
|
||||||
|
// // Get the resource handle
|
||||||
|
// uint64_t resourceRaw = resource.GetId().Raw;
|
||||||
|
|
||||||
|
// // if the barrier is not registered
|
||||||
|
// if (!handleBarriers.contains(resourceRaw))
|
||||||
|
// {
|
||||||
|
// // If the resource is a swapchain image
|
||||||
|
// bool isSwapchainImage = (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT));
|
||||||
|
// for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i)
|
||||||
|
// {
|
||||||
|
// // if swapchain image, we want the index of the swapchain image, if not take base image
|
||||||
|
// uint32_t imageIndex = isSwapchainImage ? i : 0;
|
||||||
|
|
||||||
|
// // Prepare image barrier
|
||||||
|
// vk::ImageMemoryBarrier imageBarrier
|
||||||
|
// {
|
||||||
|
// .oldLayout = colorReferences[resourceAttachmentMapping->at(resource.GetId().Raw)].layout,
|
||||||
|
// .newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
// .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
// .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
// .image = resource->GetImage(imageIndex)->GetVkImage(),
|
||||||
|
// .subresourceRange =
|
||||||
|
// {
|
||||||
|
// .aspectMask = resource->imageAspectFlags,
|
||||||
|
// .levelCount = resource->GetMipLevels(),
|
||||||
|
// .baseArrayLayer = 0,
|
||||||
|
// .layerCount = 1
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // push the barrier
|
||||||
|
// subpassComputeBarriers[i].push_back(imageBarrier);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Image transition registered
|
||||||
|
// handleBarriers.emplace(resourceRaw);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,11 @@ namespace SHADE
|
||||||
class SHRenderGraphResource;
|
class SHRenderGraphResource;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
|
class SHVkDescriptorSetGroup;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
|
class SHRenderGraphStorage;
|
||||||
|
class SHVkShaderModule;
|
||||||
|
class SHVkSampler;
|
||||||
|
|
||||||
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
||||||
{
|
{
|
||||||
|
@ -22,6 +26,8 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
|
Handle<SHRenderGraphStorage> graphStorage;
|
||||||
|
|
||||||
//! The index of the subpass in the render graph
|
//! The index of the subpass in the render graph
|
||||||
uint32_t subpassIndex;
|
uint32_t subpassIndex;
|
||||||
|
|
||||||
|
@ -43,11 +49,26 @@ namespace SHADE
|
||||||
//! Input attachments
|
//! Input attachments
|
||||||
std::vector<vk::AttachmentReference> inputReferences;
|
std::vector<vk::AttachmentReference> inputReferences;
|
||||||
|
|
||||||
|
//! This is mainly for when we want to retrieve resources using names.
|
||||||
|
std::vector<std::string> inputNames;
|
||||||
|
|
||||||
//! For getting attachment reference indices using handles
|
//! For getting attachment reference indices using handles
|
||||||
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
|
std::unordered_map<uint64_t, uint32_t> const* resourceAttachmentMapping;
|
||||||
|
|
||||||
//! Pointer to resources in the render graph (for getting handle IDs)
|
//! Descriptor set group to hold the images for input
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
std::vector<Handle<SHVkDescriptorSetGroup>> inputImageDescriptors;
|
||||||
|
|
||||||
|
//! Descriptor set layout for allocating descriptor set for inputs
|
||||||
|
Handle<SHVkDescriptorSetLayout> inputDescriptorLayout;
|
||||||
|
|
||||||
|
std::vector<Handle<SHVkSampler>> inputSamplers;
|
||||||
|
|
||||||
|
|
||||||
|
////! subpass compute image barriers. We do this because every frame has a different
|
||||||
|
////! swapchain image. If the resource we want to transition is not a swapchain image,
|
||||||
|
////! we duplicate the barrier anyway, not much memory wasted. ;)
|
||||||
|
//std::vector<std::vector<vk::ImageMemoryBarrier>> subpassComputeBarriers{};
|
||||||
|
|
||||||
|
|
||||||
//! Sometimes there exists entities that we want to render onto a render target
|
//! Sometimes there exists entities that we want to render onto a render target
|
||||||
//! but don't want it to come from the batching system. An example would be ImGUI.
|
//! but don't want it to come from the batching system. An example would be ImGUI.
|
||||||
|
@ -62,7 +83,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
SHSubpass(Handle<SHRenderGraphStorage> renderGraphStorage, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping) noexcept;
|
||||||
SHSubpass(SHSubpass&& rhs) noexcept;
|
SHSubpass(SHSubpass&& rhs) noexcept;
|
||||||
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
|
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
|
||||||
|
|
||||||
|
@ -71,15 +92,23 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Preparation functions
|
// Preparation functions
|
||||||
void AddColorOutput(std::string resourceToReference) noexcept;
|
void AddColorOutput(std::string resourceToReference) noexcept;
|
||||||
|
void AddGeneralColorOutput(std::string resourceToReference) noexcept;
|
||||||
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
|
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
|
||||||
|
void AddGeneralDepthOutput(std::string resourceToReference) noexcept;
|
||||||
void AddInput(std::string resourceToReference) noexcept;
|
void AddInput(std::string resourceToReference) noexcept;
|
||||||
|
void AddGeneralInput (std::string resourceToReference) noexcept;
|
||||||
|
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
||||||
|
|
||||||
// Runtime functions
|
// Runtime functions
|
||||||
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
|
|
||||||
void Init(SHResourceHub& resourceManager) noexcept;
|
void Init(SHResourceHub& resourceManager) noexcept;
|
||||||
|
|
||||||
|
//void InitComputeBarriers (void) noexcept;
|
||||||
|
void CreateInputDescriptors (void) noexcept;
|
||||||
|
void UpdateWriteDescriptors (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -91,5 +120,6 @@ namespace SHADE
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
|
friend class SHSubpass;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#include "SHpch.h"
|
|
||||||
#include "SHSubpassCompute.h"
|
|
||||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
SHSubpassCompute::SHSubpassCompute(Handle<SHVkPipeline> inPipeline, Handle<SHVkDescriptorPool> descPool) noexcept
|
|
||||||
: pipeline {inPipeline}
|
|
||||||
{
|
|
||||||
// Get the descriptor set layouts required to allocate. we will bind a different pipeline layout, one that includes the layout for global.
|
|
||||||
auto const& layouts = pipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate();
|
|
||||||
|
|
||||||
// Variable counts for the descriptor sets (all should be 1).
|
|
||||||
std::vector<uint32_t> variableCounts{static_cast<uint32_t>(layouts.size())};
|
|
||||||
std::fill (variableCounts.begin(), variableCounts.end(), 0);
|
|
||||||
|
|
||||||
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
|
||||||
descPool->Allocate(layouts, variableCounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <Resource/SHHandle.h>
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
class SHVkPipeline;
|
|
||||||
class SHVkDescriptorSetGroup;
|
|
||||||
class SHVkDescriptorPool;
|
|
||||||
|
|
||||||
class SHSubpassCompute
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
//! To run the dispatch command
|
|
||||||
Handle<SHVkPipeline> pipeline;
|
|
||||||
|
|
||||||
//! Descriptor set group
|
|
||||||
Handle<SHVkDescriptorSetGroup> descSetGroup;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SHSubpassCompute (Handle<SHVkPipeline> inPipeline, Handle<SHVkDescriptorPool> descPool) noexcept;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,6 +55,21 @@ namespace SHADE
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vk::PipelineBindPoint SHVkUtil::GetPipelineBindPointFromType(SH_PIPELINE_TYPE pipelineType) noexcept
|
||||||
|
{
|
||||||
|
switch (pipelineType)
|
||||||
|
{
|
||||||
|
case SH_PIPELINE_TYPE::GRAPHICS:
|
||||||
|
return vk::PipelineBindPoint::eGraphics;
|
||||||
|
case SH_PIPELINE_TYPE::COMPUTE:
|
||||||
|
return vk::PipelineBindPoint::eCompute;
|
||||||
|
case SH_PIPELINE_TYPE::RAY_TRACING:
|
||||||
|
return vk::PipelineBindPoint::eRayTracingKHR;
|
||||||
|
default:
|
||||||
|
return vk::PipelineBindPoint::eGraphics;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkUtil::EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage)
|
void SHVkUtil::EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage)
|
||||||
{
|
{
|
||||||
if (bufferHandle)
|
if (bufferHandle)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "SHVulkanIncludes.h"
|
#include "SHVulkanIncludes.h"
|
||||||
|
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -24,6 +25,7 @@ namespace SHADE
|
||||||
static bool IsDepthStencilAttachment (vk::Format format) noexcept;
|
static bool IsDepthStencilAttachment (vk::Format format) noexcept;
|
||||||
static bool IsBlendCompatible (vk::Format format) noexcept;
|
static bool IsBlendCompatible (vk::Format format) noexcept;
|
||||||
static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept;
|
static uint32_t GetBytesPerPixelFromFormat (vk::Format format) noexcept;
|
||||||
|
static vk::PipelineBindPoint GetPipelineBindPointFromType (SH_PIPELINE_TYPE pipelineType) noexcept;
|
||||||
|
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -177,6 +177,9 @@ namespace SHADE
|
||||||
return vk::DescriptorType::eStorageBufferDynamic;
|
return vk::DescriptorType::eStorageBufferDynamic;
|
||||||
case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||||
return vk::DescriptorType::eInputAttachment;
|
return vk::DescriptorType::eInputAttachment;
|
||||||
|
case SpvReflectDescriptorType::SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||||
|
return vk::DescriptorType::eStorageImage;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return vk::DescriptorType::eCombinedImageSampler;
|
return vk::DescriptorType::eCombinedImageSampler;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,6 +20,10 @@ namespace SHADE
|
||||||
/* Static defines */
|
/* Static defines */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHInputManager::controllerInUse = false;
|
||||||
|
|
||||||
|
std::map<std::string, SHInputManager::SHLogicalBindingData> SHInputManager::bindings;
|
||||||
|
|
||||||
unsigned SHInputManager::keyCount = 0;
|
unsigned SHInputManager::keyCount = 0;
|
||||||
bool SHInputManager::keys[MAX_KEYS];
|
bool SHInputManager::keys[MAX_KEYS];
|
||||||
bool SHInputManager::keysLast[MAX_KEYS];
|
bool SHInputManager::keysLast[MAX_KEYS];
|
||||||
|
@ -41,6 +45,60 @@ namespace SHADE
|
||||||
int SHInputManager::mouseWheelVerticalDelta = 0;
|
int SHInputManager::mouseWheelVerticalDelta = 0;
|
||||||
int SHInputManager::mouseWheelVerticalDeltaPoll = 0;
|
int SHInputManager::mouseWheelVerticalDeltaPoll = 0;
|
||||||
|
|
||||||
|
unsigned char SHInputManager::controllersConnectedCount = 0;
|
||||||
|
unsigned SHInputManager::controllersInputCount[XUSER_MAX_COUNT];
|
||||||
|
unsigned SHInputManager::controllersButtonCount[XUSER_MAX_COUNT];
|
||||||
|
short SHInputManager::controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
short SHInputManager::controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
double SHInputManager::controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
double SHInputManager::controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
|
||||||
|
//Internal helper function for splitting between inputs
|
||||||
|
bool SHInputManager::controllerConsideredHeld(size_t inputIdx, short value) noexcept
|
||||||
|
{
|
||||||
|
if (inputIdx >= MAX_CONTROLLER_INPUT) return false; //Bounds check
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (inputIdx < NUM_CONTROLLER_BUTTON)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(value);
|
||||||
|
}
|
||||||
|
else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER)
|
||||||
|
{
|
||||||
|
return (value > XINPUT_GAMEPAD_TRIGGER_THRESHOLD);
|
||||||
|
}
|
||||||
|
else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER + NUM_CONTROLLER_TRIGGER)
|
||||||
|
{
|
||||||
|
return (std::abs(value) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (std::abs(value) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Internal helper function for getting normalised input value
|
||||||
|
double SHInputManager::controllerNormalisedValue(size_t inputIdx, short value) noexcept
|
||||||
|
{
|
||||||
|
if (inputIdx >= MAX_CONTROLLER_INPUT) return 0.0; //Bounds check
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (inputIdx < NUM_CONTROLLER_BUTTON)
|
||||||
|
{
|
||||||
|
return static_cast<double>(value);
|
||||||
|
}
|
||||||
|
else if (inputIdx < NUM_CONTROLLER_BUTTON + NUM_CONTROLLER_TRIGGER) //8-bit triggers, 0 to 255
|
||||||
|
{
|
||||||
|
return static_cast<double>(value) / static_cast<double>(UCHAR_MAX);
|
||||||
|
}
|
||||||
|
else //16-bit thumbsticks, -32768 to 32767
|
||||||
|
{
|
||||||
|
return static_cast<double>(value) / static_cast<double>(SHRT_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHInputManager::UpdateInput(double dt) noexcept
|
void SHInputManager::UpdateInput(double dt) noexcept
|
||||||
{
|
{
|
||||||
//Keyboard and Mouse Buttons////////////////////////////////////////////////
|
//Keyboard and Mouse Buttons////////////////////////////////////////////////
|
||||||
|
@ -120,6 +178,273 @@ namespace SHADE
|
||||||
mouseWheelVerticalDelta = 0;
|
mouseWheelVerticalDelta = 0;
|
||||||
mouseWheelVerticalDelta = mouseWheelVerticalDeltaPoll;
|
mouseWheelVerticalDelta = mouseWheelVerticalDeltaPoll;
|
||||||
mouseWheelVerticalDeltaPoll = 0;
|
mouseWheelVerticalDeltaPoll = 0;
|
||||||
|
|
||||||
|
//Controllers//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
controllersConnectedCount = 0;
|
||||||
|
|
||||||
|
//Set last controller states
|
||||||
|
memcpy(controllersLast, controllers, sizeof(controllers));
|
||||||
|
|
||||||
|
//Reset controller states
|
||||||
|
SecureZeroMemory(&controllers, sizeof(controllers));
|
||||||
|
|
||||||
|
//https://learn.microsoft.com/en-us/windows/win32/xinput/getting-started-with-xinput#getting-controller-state
|
||||||
|
for (DWORD c = 0; c < XUSER_MAX_COUNT; ++c)
|
||||||
|
{
|
||||||
|
controllersInputCount[c] = 0;
|
||||||
|
controllersButtonCount[c] = 0;
|
||||||
|
|
||||||
|
XINPUT_STATE state;
|
||||||
|
SecureZeroMemory(&state, sizeof(XINPUT_STATE));
|
||||||
|
|
||||||
|
//Get the state of controller from XInput
|
||||||
|
DWORD result = XInputGetState(c, &state);
|
||||||
|
|
||||||
|
//Write gamepad data
|
||||||
|
if (result == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
++controllersConnectedCount;
|
||||||
|
|
||||||
|
//DIGITAL BUTTONS///////////////////////////////////////
|
||||||
|
|
||||||
|
//DPAD UP
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_UP)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_UP)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//DPAD DOWN
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_DOWN)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_DOWN)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//DPAD LEFT
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_LEFT)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_LEFT)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//DPAD RIGHT
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_RIGHT)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::DPAD_RIGHT)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//START
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::START)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::START)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//BACK
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::BACK)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::BACK)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//LEFT THUMBSTICK BUTTON
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//RIGHT THUMBSTICK BUTTON
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//LEFT SHOULDER BUTTON
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_SHOULDER)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_SHOULDER)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//RIGHT SHOULDER BUTTON
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_SHOULDER)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_SHOULDER)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//A
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::A)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::A)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//B
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::B)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::B)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//X
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::X)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::X)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Y
|
||||||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::Y)] = 1;
|
||||||
|
++controllersInputCount[c];
|
||||||
|
++controllersButtonCount[c];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::Y)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//8 BIT VALUES (0 - 255)///////////////////////////////////
|
||||||
|
|
||||||
|
//LEFT TRIGGER
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_TRIGGER)] = state.Gamepad.bLeftTrigger;
|
||||||
|
if (state.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||||
|
{
|
||||||
|
++controllersInputCount[c]; //Registered as held
|
||||||
|
}
|
||||||
|
|
||||||
|
//RIGHT TRIGGER
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_TRIGGER)] = state.Gamepad.bRightTrigger;
|
||||||
|
if (state.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||||
|
{
|
||||||
|
++controllersInputCount[c]; //Registered as held
|
||||||
|
}
|
||||||
|
|
||||||
|
//16 BIT VALUES (0 - 65535)////////////////////////////////
|
||||||
|
|
||||||
|
//LEFT THUMBSTICK X
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK_X)] = state.Gamepad.sThumbLX;
|
||||||
|
if (std::abs(state.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
|
||||||
|
{
|
||||||
|
++controllersInputCount[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
//LEFT THUMBSTICK Y
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::LEFT_THUMBSTICK_Y)] = state.Gamepad.sThumbLY;
|
||||||
|
if (std::abs(state.Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
|
||||||
|
{
|
||||||
|
++controllersInputCount[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
//RIGHT THUMBSTICK X
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK_X)] = state.Gamepad.sThumbRX;
|
||||||
|
if (std::abs(state.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
|
||||||
|
{
|
||||||
|
++controllersInputCount[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
//RIGHT THUMBSTICK Y
|
||||||
|
controllers[c][static_cast<size_t>(SH_CONTROLLERCODE::RIGHT_THUMBSTICK_Y)] = state.Gamepad.sThumbRY;
|
||||||
|
if (std::abs(state.Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
|
||||||
|
{
|
||||||
|
++controllersInputCount[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Timers and updating if controller is presently in use
|
||||||
|
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||||
|
{
|
||||||
|
if (controllerConsideredHeld(i, controllers[c][i])) //Considered on
|
||||||
|
{
|
||||||
|
controllerInUse = true;
|
||||||
|
if (!controllerConsideredHeld(i, controllersLast[c][i])) //Just on
|
||||||
|
{
|
||||||
|
controllersHeldTime[c][i] = 0.0; //Reset timer
|
||||||
|
}
|
||||||
|
controllersHeldTime[c][i] += dt; //Tick up
|
||||||
|
}
|
||||||
|
else //Considered off
|
||||||
|
{
|
||||||
|
if (controllerConsideredHeld(i, controllersLast[c][i])) //Just off
|
||||||
|
{
|
||||||
|
controllersReleasedTime[c][i] = 0.0; //Reset timer
|
||||||
|
}
|
||||||
|
controllersReleasedTime[c][i] += dt; //Tick up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHInputManager::AnyKeyDown(SH_KEYCODE* firstDetected) noexcept
|
bool SHInputManager::AnyKeyDown(SH_KEYCODE* firstDetected) noexcept
|
||||||
|
@ -161,4 +486,336 @@ namespace SHADE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Any controller input being held
|
||||||
|
//For analog, this means going being deadzone values
|
||||||
|
bool SHInputManager::AnyControllerInput(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||||
|
{
|
||||||
|
if (controllerConsideredHeld(i, controllers[cNum][i]))
|
||||||
|
{
|
||||||
|
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::AnyControllerInputDown(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||||
|
{
|
||||||
|
if (controllerConsideredHeld(i, controllers[cNum][i]) && !controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||||
|
{
|
||||||
|
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::AnyControllerInputUp(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
for (size_t i = 0; i < MAX_CONTROLLER_INPUT; ++i)
|
||||||
|
{
|
||||||
|
if (!controllerConsideredHeld(i, controllers[cNum][i]) && controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||||
|
{
|
||||||
|
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::AnyControllerButton(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i)
|
||||||
|
{
|
||||||
|
if (controllerConsideredHeld(i, controllers[cNum][i]))
|
||||||
|
{
|
||||||
|
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::AnyControllerButtonDown(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i)
|
||||||
|
{
|
||||||
|
if (controllerConsideredHeld(i, controllers[cNum][i]) && !controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||||
|
{
|
||||||
|
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::AnyControllerButtonUp(SH_CONTROLLERCODE* firstDetected, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
for (size_t i = 0; i < NUM_CONTROLLER_BUTTON; ++i)
|
||||||
|
{
|
||||||
|
if (!controllerConsideredHeld(i, controllers[cNum][i]) && controllerConsideredHeld(i, controllersLast[cNum][i]))
|
||||||
|
{
|
||||||
|
if (firstDetected) *firstDetected = static_cast<SH_CONTROLLERCODE>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Only get of largest magnitude
|
||||||
|
double SHInputManager::GetBindingAxis(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
//Over keycodes, prioritise positive
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKey(k)) return 1.0;
|
||||||
|
}
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKey(k)) return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double largestMagnitude = 0.0;
|
||||||
|
|
||||||
|
//Over controllerCodes
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||||
|
{
|
||||||
|
double newValue = 0.0;
|
||||||
|
if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum))
|
||||||
|
if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = newValue;
|
||||||
|
}
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||||
|
{
|
||||||
|
double newValue = 0.0;
|
||||||
|
if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum))
|
||||||
|
if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = -newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return largestMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::GetBindingPositiveButton(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKey(k)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::GetBindingNegativeButton(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKey(k)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::GetBindingPositiveButtonDown(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyDown(k)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputDown(c, nullptr, cNum)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::GetBindingNegativeButtonDown(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyDown(k)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputDown(c, nullptr, cNum)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::GetBindingPositiveButtonUp(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyUp(k)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputUp(c, nullptr, cNum)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHInputManager::GetBindingNegativeButtonUp(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyUp(k)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputUp(c, nullptr, cNum)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fetches longest hold time
|
||||||
|
double SHInputManager::GetBindingPositiveHeldTime(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||||
|
|
||||||
|
double maxHeldTime = 0.0;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxHeldTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SHInputManager::GetBindingNegativeHeldTime(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||||
|
|
||||||
|
double maxHeldTime = 0.0;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxHeldTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fetches shortest release time
|
||||||
|
double SHInputManager::GetBindingPositiveReleasedTime(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||||
|
|
||||||
|
double minReleaseTime = _HUGE_ENUF;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return minReleaseTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SHInputManager::GetBindingNegativeReleasedTime(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||||
|
|
||||||
|
double minReleaseTime = _HUGE_ENUF;
|
||||||
|
|
||||||
|
//Over keycodes
|
||||||
|
for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes)
|
||||||
|
{
|
||||||
|
if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Over controller buttons
|
||||||
|
for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes)
|
||||||
|
{
|
||||||
|
if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return minReleaseTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Only for mouse movement
|
||||||
|
//Get largest delta
|
||||||
|
double SHInputManager::GetBindingMouseVelocity(std::string bindingName, size_t cNum) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return 0.0;
|
||||||
|
|
||||||
|
//Mouse velocity
|
||||||
|
double velX = 0.0;
|
||||||
|
double velY = 0.0;
|
||||||
|
GetMouseVelocity(&velX, &velY);
|
||||||
|
|
||||||
|
return bindings[bindingName].mouseXPositiveMultiplier * velX + bindings[bindingName].mouseYPositiveMultiplier * velY;
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace SHADE
|
} //namespace SHADE
|
|
@ -10,9 +10,12 @@
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
//#include <Xinput.h>
|
#include <Xinput.h>
|
||||||
//#include "../../SHADE_Managed/src/SHpch.h"
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include "../../SHADE_Managed/src/SHpch.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#pragma comment(lib, "xinput.lib")
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -268,6 +271,58 @@ namespace SHADE
|
||||||
OEM_CLEAR
|
OEM_CLEAR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SH_CONTROLLERCODE
|
||||||
|
{
|
||||||
|
//Digital
|
||||||
|
DPAD_UP,
|
||||||
|
DPAD_DOWN,
|
||||||
|
DPAD_LEFT,
|
||||||
|
DPAD_RIGHT,
|
||||||
|
START,
|
||||||
|
BACK,
|
||||||
|
LEFT_THUMBSTICK,
|
||||||
|
RIGHT_THUMBSTICK,
|
||||||
|
LEFT_SHOULDER,
|
||||||
|
RIGHT_SHOULDER,
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
|
||||||
|
//1 Byte Unsigned Analog
|
||||||
|
LEFT_TRIGGER,
|
||||||
|
RIGHT_TRIGGER,
|
||||||
|
|
||||||
|
//2 Byte Signed Analog
|
||||||
|
LEFT_THUMBSTICK_X,
|
||||||
|
LEFT_THUMBSTICK_Y,
|
||||||
|
RIGHT_THUMBSTICK_X,
|
||||||
|
RIGHT_THUMBSTICK_Y
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Struct for logical bindings */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
struct SH_API SHLogicalBindingData
|
||||||
|
{
|
||||||
|
//Key codes mapped to positive
|
||||||
|
std::set<SH_KEYCODE> positiveKeyCodes;
|
||||||
|
|
||||||
|
//Key codes mapped to negative
|
||||||
|
std::set<SH_KEYCODE> negativeKeyCodes;
|
||||||
|
|
||||||
|
//Controller Codes mapped to positive
|
||||||
|
std::set<SH_CONTROLLERCODE> positiveControllerCodes;
|
||||||
|
|
||||||
|
//Controller Codes mapped to negative
|
||||||
|
std::set<SH_CONTROLLERCODE> negativeControllerCodes;
|
||||||
|
|
||||||
|
//Mouse movement mapped to axes?
|
||||||
|
double mouseXPositiveMultiplier;
|
||||||
|
double mouseYPositiveMultiplier;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//Updates current state of the input, with dt to be fetched from FRC
|
//Updates current state of the input, with dt to be fetched from FRC
|
||||||
//TODO should dt be fixed or variable?
|
//TODO should dt be fixed or variable?
|
||||||
|
@ -392,7 +447,7 @@ namespace SHADE
|
||||||
keysToggleLast[static_cast<int>(key)]);
|
keysToggleLast[static_cast<int>(key)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mouse/////////////
|
//Mouse/////////////////////////////////////////////////////
|
||||||
|
|
||||||
//Get the mouse location with respect to the screen
|
//Get the mouse location with respect to the screen
|
||||||
static inline void GetMouseScreenPosition (int* x = nullptr,
|
static inline void GetMouseScreenPosition (int* x = nullptr,
|
||||||
|
@ -428,7 +483,95 @@ namespace SHADE
|
||||||
return mouseWheelVerticalDelta;
|
return mouseWheelVerticalDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
//GET INPUT TIMINGS///////////////////////////////////////////////////////////
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Input state accessors (KB & M) */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//How many controller inputs of any kind are being used now
|
||||||
|
static inline unsigned GetControllerInputCount(size_t cNum = 0) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return 0;
|
||||||
|
return controllersInputCount[cNum];
|
||||||
|
}
|
||||||
|
|
||||||
|
//How many controller buttons are being pressed now
|
||||||
|
//Subtract from getControllerInputCount() for analog triggers / thumbsticks
|
||||||
|
static inline unsigned GetControllerButtonCount(size_t cNum = 0) noexcept
|
||||||
|
{
|
||||||
|
if (cNum >= XUSER_MAX_COUNT) return 0;
|
||||||
|
return controllersButtonCount[cNum];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Any controller input being held
|
||||||
|
//For analog, this means going being deadzone values
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static bool AnyControllerInput(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||||
|
|
||||||
|
//Any controller input activated in THIS FRAME ONLY
|
||||||
|
//For analog, this means going being deadzone values
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static bool AnyControllerInputDown(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||||
|
|
||||||
|
//Any controller input deactivated in THIS FRAME ONLY
|
||||||
|
//For analog, this means going below deadzone values
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static bool AnyControllerInputUp(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||||
|
|
||||||
|
//Any DIGITAL controller buttons being held
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static bool AnyControllerButton(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||||
|
|
||||||
|
//Any DIGITAL controller button activated in THIS FRAME ONLY
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static bool AnyControllerButtonDown(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||||
|
|
||||||
|
//Any DIGITAL controller button deactivated in THIS FRAME ONLY
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static bool AnyControllerButtonUp(SH_CONTROLLERCODE* firstDetected = nullptr, size_t controllerNum = 0) noexcept;
|
||||||
|
|
||||||
|
//If controller input is being held in the current frame
|
||||||
|
//normalisedValue is the value of the input between 0 and 1, relevant for trigger and thumbstick data
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static inline bool GetControllerInput(SH_CONTROLLERCODE input,
|
||||||
|
double* normalisedValue = nullptr,
|
||||||
|
double* heldTime = nullptr,
|
||||||
|
double* releasedTime = nullptr,
|
||||||
|
size_t controllerNum = 0) noexcept
|
||||||
|
{
|
||||||
|
if (controllerNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
if (normalisedValue) *normalisedValue = controllerNormalisedValue(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]);
|
||||||
|
if (heldTime) *heldTime = controllersHeldTime[controllerNum][static_cast<size_t>(input)];
|
||||||
|
if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast<size_t>(input)];
|
||||||
|
return controllerConsideredHeld(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If controller input was considered to be held down in THIS FRAME ONLY
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static inline bool GetControllerInputDown(SH_CONTROLLERCODE input,
|
||||||
|
double* releasedTime = nullptr,
|
||||||
|
size_t controllerNum = 0) noexcept
|
||||||
|
{
|
||||||
|
if (controllerNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast<size_t>(input)];
|
||||||
|
return (controllerConsideredHeld(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]) &&
|
||||||
|
!controllerConsideredHeld(static_cast<size_t>(input), controllersLast[controllerNum][static_cast<size_t>(input)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
//If controller input was considered to be released in THIS FRAME ONLY
|
||||||
|
//controllerNum should be between 0 and 3
|
||||||
|
static inline bool GetControllerInputUp(SH_CONTROLLERCODE input,
|
||||||
|
double* releasedTime = nullptr,
|
||||||
|
size_t controllerNum = 0) noexcept
|
||||||
|
{
|
||||||
|
if (controllerNum >= XUSER_MAX_COUNT) return false;
|
||||||
|
if (releasedTime) *releasedTime = controllersReleasedTime[controllerNum][static_cast<size_t>(input)];
|
||||||
|
return (!controllerConsideredHeld(static_cast<size_t>(input), controllers[controllerNum][static_cast<size_t>(input)]) &&
|
||||||
|
controllerConsideredHeld(static_cast<size_t>(input), controllersLast[controllerNum][static_cast<size_t>(input)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Timing accessors */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//Keyboard/////////////
|
//Keyboard/////////////
|
||||||
|
|
||||||
|
@ -456,6 +599,191 @@ namespace SHADE
|
||||||
return keysToggleOffTime[static_cast<int>(key)];
|
return keysToggleOffTime[static_cast<int>(key)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Controller//////////////////////
|
||||||
|
|
||||||
|
//How long has this controller input been considered to be held down for
|
||||||
|
static inline double GetControllerInputHeldTime(SH_CONTROLLERCODE code,
|
||||||
|
size_t controllerNum = 0) noexcept
|
||||||
|
{
|
||||||
|
if (controllerNum >= XUSER_MAX_COUNT) return 0.0;
|
||||||
|
return controllersHeldTime[controllerNum][static_cast<size_t>(code)];
|
||||||
|
}
|
||||||
|
|
||||||
|
//How long has this controller input been considered to be released for
|
||||||
|
static inline double GetControllerInputReleasedTime(SH_CONTROLLERCODE code,
|
||||||
|
size_t controllerNum = 0) noexcept
|
||||||
|
{
|
||||||
|
if (controllerNum >= XUSER_MAX_COUNT) return 0.0;
|
||||||
|
return controllersReleasedTime[controllerNum][static_cast<size_t>(code)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Binding Functions */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//Add a new binding to the map
|
||||||
|
static inline void BindingsAdd(std::string newBindingName) noexcept
|
||||||
|
{
|
||||||
|
bindings.insert({ newBindingName, SHLogicalBindingData() });
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove a binding from the map
|
||||||
|
//Returns 1 if found and removed, 0 if not found
|
||||||
|
static inline size_t BindingsRemove(std::string targetBindingName) noexcept
|
||||||
|
{
|
||||||
|
return bindings.erase(targetBindingName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Clears all bindings from the list
|
||||||
|
static inline void BindingsClear() noexcept
|
||||||
|
{
|
||||||
|
bindings.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the number of bindings present
|
||||||
|
static inline size_t BindingsCount() noexcept
|
||||||
|
{
|
||||||
|
return bindings.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check positive keycodes to binding
|
||||||
|
static inline std::set<SH_KEYCODE> const& BindingsGetPositiveKeyCodes(std::string bindingName) noexcept
|
||||||
|
{
|
||||||
|
return bindings[bindingName].positiveKeyCodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add positive SH_KEYCODE to binding
|
||||||
|
static inline void BindingsAddPositiveKeyCode(std::string targetBindingName,
|
||||||
|
SH_KEYCODE toAdd) noexcept
|
||||||
|
{
|
||||||
|
bindings[targetBindingName].positiveKeyCodes.insert(toAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove positive SH_KEYCODE from binding
|
||||||
|
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||||
|
static inline size_t BindingsRemovePositiveKeyCode(std::string targetBindingName,
|
||||||
|
SH_KEYCODE toRemove) noexcept
|
||||||
|
{
|
||||||
|
return bindings[targetBindingName].positiveKeyCodes.erase(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check negative keycodes to binding
|
||||||
|
static inline std::set<SH_KEYCODE> const& BindingsGetNegativeKeyCodes(std::string bindingName) noexcept
|
||||||
|
{
|
||||||
|
return bindings[bindingName].negativeKeyCodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add negative SH_KEYCODE to binding
|
||||||
|
static inline void BindingsAddNegativeKeyCode(std::string targetBindingName,
|
||||||
|
SH_KEYCODE toAdd) noexcept
|
||||||
|
{
|
||||||
|
bindings[targetBindingName].negativeKeyCodes.insert(toAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove negative SH_KEYCODE from binding
|
||||||
|
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||||
|
static inline size_t BindingsRemoveNegativeKeyCode(std::string targetBindingName,
|
||||||
|
SH_KEYCODE toRemove) noexcept
|
||||||
|
{
|
||||||
|
return bindings[targetBindingName].negativeKeyCodes.erase(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check positive controllercodes to binding
|
||||||
|
static inline std::set<SH_CONTROLLERCODE> const& BindingsGetPositiveControllerCodes(std::string bindingName) noexcept
|
||||||
|
{
|
||||||
|
return bindings[bindingName].positiveControllerCodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add positive SH_CONTROLLERCODE to binding
|
||||||
|
static inline void BindingsAddPositiveControllerCode(std::string targetBindingName,
|
||||||
|
SH_CONTROLLERCODE toAdd) noexcept
|
||||||
|
{
|
||||||
|
bindings[targetBindingName].positiveControllerCodes.insert(toAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove positive SH_CONTROLLERCODE from binding
|
||||||
|
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||||
|
static inline size_t BindingsRemovePositiveControllerCode(std::string targetBindingName,
|
||||||
|
SH_CONTROLLERCODE toRemove) noexcept
|
||||||
|
{
|
||||||
|
return bindings[targetBindingName].positiveControllerCodes.erase(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check negative controllercodes to binding
|
||||||
|
static inline std::set<SH_CONTROLLERCODE> const& BindingsGetNegativeControllerCodes(std::string bindingName) noexcept
|
||||||
|
{
|
||||||
|
return bindings[bindingName].negativeControllerCodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add negative SH_CONTROLLERCODE to binding
|
||||||
|
static inline void BindingsAddNegativeControllerCode(std::string targetBindingName,
|
||||||
|
SH_CONTROLLERCODE toAdd) noexcept
|
||||||
|
{
|
||||||
|
bindings[targetBindingName].negativeControllerCodes.insert(toAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remove negative SH_CONTROLLERCODE from binding
|
||||||
|
//If toRemove found and removed, returns 1. Otherwise, 0.
|
||||||
|
static inline size_t BindingsRemoveNegativeControllerCode(std::string targetBindingName,
|
||||||
|
SH_CONTROLLERCODE toRemove) noexcept
|
||||||
|
{
|
||||||
|
return bindings[targetBindingName].negativeControllerCodes.erase(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mouse movement bindings
|
||||||
|
|
||||||
|
static inline double const BindingsGetMouseXPositiveMultiplier(std::string bindingName) noexcept
|
||||||
|
{
|
||||||
|
return bindings[bindingName].mouseXPositiveMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void BindingsSetMouseXPositiveMultiplier(std::string bindingName, double newValue) noexcept
|
||||||
|
{
|
||||||
|
bindings[bindingName].mouseXPositiveMultiplier = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double const BindingsGetMouseYPositiveMultiplier(std::string bindingName) noexcept
|
||||||
|
{
|
||||||
|
return bindings[bindingName].mouseXPositiveMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void BindingsSetMouseYPositiveMultiplier(std::string bindingName, double newValue) noexcept
|
||||||
|
{
|
||||||
|
bindings[bindingName].mouseXPositiveMultiplier = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the axis value of binding, between -1 and 1
|
||||||
|
static double GetBindingAxis(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
|
//Whether binding is being held or not
|
||||||
|
//Does not work for mouse movement
|
||||||
|
static bool GetBindingPositiveButton(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
static bool GetBindingNegativeButton(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
|
//Whether binding is pressed down IN THIS FRAME ONLY
|
||||||
|
//Does not work for mouse movement
|
||||||
|
static bool GetBindingPositiveButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
static bool GetBindingNegativeButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
|
//Whether binding is released IN THIS FRAME ONLY
|
||||||
|
//Does not work for mouse movement
|
||||||
|
static bool GetBindingPositiveButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
static bool GetBindingNegativeButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
|
//Binding times
|
||||||
|
|
||||||
|
//Does not work for mouse movement
|
||||||
|
static double GetBindingPositiveHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
static double GetBindingNegativeHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
|
//Does not work for mouse movement
|
||||||
|
static double GetBindingPositiveReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
static double GetBindingNegativeReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
|
//Binding mouse velocity
|
||||||
|
//Only for mouse movement
|
||||||
|
static double GetBindingMouseVelocity(std::string bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
/* Other Functions */
|
/* Other Functions */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
@ -482,10 +810,36 @@ namespace SHADE
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
static constexpr size_t MAX_KEYS = UCHAR_MAX + 1;
|
static constexpr size_t MAX_KEYS = UCHAR_MAX + 1;
|
||||||
|
|
||||||
|
//How many recognised controller inputs there are
|
||||||
|
//To see the list, see the enum class in this file
|
||||||
|
static constexpr size_t MAX_CONTROLLER_INPUT = 20;
|
||||||
|
|
||||||
|
//On/off button count
|
||||||
|
static constexpr size_t NUM_CONTROLLER_BUTTON = 14;
|
||||||
|
|
||||||
|
//8-bit trigger values
|
||||||
|
static constexpr size_t NUM_CONTROLLER_TRIGGER = 2;
|
||||||
|
|
||||||
|
//16-bit thumbstick values
|
||||||
|
static constexpr size_t NUM_CONTROLLER_THUMBSTICK = 4;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//If the last input is from controller(s) or KB/M
|
||||||
|
//True if from controller(s), False if from KB/M
|
||||||
|
//Useful for switching control hints between controllers and KB/M
|
||||||
|
static bool controllerInUse;
|
||||||
|
|
||||||
|
//BINDINGS//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//Key is for binding names, they must be unique
|
||||||
|
//Multiple physical inputs per virtual/logical input are to be added to
|
||||||
|
//sets inside the logicalBinding values
|
||||||
|
//TODO make this an array of 4 / 5 users for multiplayer support
|
||||||
|
static std::map<std::string, SHLogicalBindingData> bindings;
|
||||||
|
|
||||||
//KEYBOARD AND MOUSE BUTTONS////////////////////////////////////////////////
|
//KEYBOARD AND MOUSE BUTTONS////////////////////////////////////////////////
|
||||||
|
|
||||||
//How many keys are presently being pressed
|
//How many keys are presently being pressed
|
||||||
|
@ -558,15 +912,48 @@ namespace SHADE
|
||||||
|
|
||||||
//CONTROLLER VARIABLES//////////////////////////////////////////////////////
|
//CONTROLLER VARIABLES//////////////////////////////////////////////////////
|
||||||
|
|
||||||
//OTHER VARIABLES///////////////////////////////////////////////////////////
|
//Count how many controllers are presently connected
|
||||||
|
//Useful for if the game is to decide to take in controller or KB/M input
|
||||||
|
//Between 0 and 4 (inclusive)
|
||||||
|
static unsigned char controllersConnectedCount;
|
||||||
|
|
||||||
//Axis bindings
|
//How many inputs (of any kind) on the controller are being used now
|
||||||
//X
|
//Includes analog triggers and thumbsticks
|
||||||
|
static unsigned controllersInputCount[XUSER_MAX_COUNT];
|
||||||
|
|
||||||
//Y
|
//How many DIGITAL buttons on the controller are being pressed now
|
||||||
|
static unsigned controllersButtonCount[XUSER_MAX_COUNT];
|
||||||
|
|
||||||
//Other mappings
|
//Current state of controllers
|
||||||
|
//First index is for controller number
|
||||||
|
//Second index is for input type
|
||||||
|
static short controllers[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
|
||||||
//Buffer
|
//State of controllers in the last frame
|
||||||
|
//First index is for controller number
|
||||||
|
//Second index is for input type
|
||||||
|
static short controllersLast[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
|
||||||
|
//Held and released times
|
||||||
|
|
||||||
|
//Controller held durations
|
||||||
|
//Stops ticking up when released
|
||||||
|
//Will be reset when held again
|
||||||
|
static double controllersHeldTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
|
||||||
|
//Key released durations
|
||||||
|
//Stops ticking up when held
|
||||||
|
//Will be reset when off again
|
||||||
|
static double controllersReleasedTime[XUSER_MAX_COUNT][MAX_CONTROLLER_INPUT];
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Internal Helper Functions */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//Internal helper function for checking if input is considered held or not
|
||||||
|
static bool controllerConsideredHeld(size_t inputIdx, short value) noexcept;
|
||||||
|
|
||||||
|
//Internal helper function for getting normalised controller value
|
||||||
|
static double controllerNormalisedValue(size_t inputIdx, short value) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
//#version 450
|
||||||
|
//
|
||||||
|
//layout(local_size_x = 16, local_size_y = 16) in;
|
||||||
|
//layout(set = 4, binding = 0, rgba8) uniform image2D targetImage;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//void main()
|
||||||
|
//{
|
||||||
|
// ivec2 imageSize = imageSize (targetImage);
|
||||||
|
//
|
||||||
|
// if (gl_GlobalInvocationID.x >= imageSize.x && gl_GlobalInvocationID.y >= imageSize.y)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// // load the image
|
||||||
|
// vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID));
|
||||||
|
//
|
||||||
|
// // get the average
|
||||||
|
// float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
|
||||||
|
//
|
||||||
|
// // store result into result image
|
||||||
|
// imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f));
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
/* Start Header *****************************************************************/
|
||||||
|
|
||||||
|
/*! \file (e.g. kirsch.comp)
|
||||||
|
|
||||||
|
\author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920.
|
||||||
|
|
||||||
|
\par william.zheng\@digipen.edu. brandon.hao\@digipen.edu.
|
||||||
|
|
||||||
|
\date Sept 20, 2022
|
||||||
|
|
||||||
|
\brief Copyright (C) 20xx DigiPen Institute of Technology.
|
||||||
|
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. */
|
||||||
|
|
||||||
|
/* End Header *******************************************************************/
|
||||||
|
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
#define MASK_WIDTH 3
|
||||||
|
#define HALF_M_WIDTH MASK_WIDTH / 2
|
||||||
|
#define SHM_WIDTH 18
|
||||||
|
#define NUM_MASKS 8
|
||||||
|
|
||||||
|
layout(local_size_x = 16, local_size_y = 16) in;
|
||||||
|
layout(set = 4, binding = 0, rgba8) uniform image2D inputImage;
|
||||||
|
layout(set = 4, binding = 1, rgba8) uniform image2D resultImage;
|
||||||
|
|
||||||
|
const float kirsch[8][3][3] = {
|
||||||
|
{
|
||||||
|
{5, 5, 5},
|
||||||
|
{-3, 0, -3}, /*rotation 1 */
|
||||||
|
{-3, -3, -3}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{5, 5, -3},
|
||||||
|
{5, 0, -3}, /*rotation 2 */
|
||||||
|
{-3, -3, -3}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{5, -3, -3},
|
||||||
|
{5, 0, -3}, /*rotation 3 */
|
||||||
|
{5, -3, -3}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{-3, -3, -3},
|
||||||
|
{5, 0, -3}, /*rotation 4 */
|
||||||
|
{5, 5, -3}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{-3, -3, -3},
|
||||||
|
{-3, 0, -3}, /*rotation 5 */
|
||||||
|
{5, 5, 5}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{-3, -3, -3},
|
||||||
|
{-3, 0, 5}, /*rotation 6 */
|
||||||
|
{-3, 5, 5}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{-3, -3, 5},
|
||||||
|
{-3, 0, 5}, /*rotation 7 */
|
||||||
|
{-3, -3, 5}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{-3, 5, 5},
|
||||||
|
{-3, 0, 5}, /*rotation 8 */
|
||||||
|
{-3, -3, -3}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vec3 GetImageValues(ivec2 uv, ivec2 inputImageSize)
|
||||||
|
{
|
||||||
|
if (uv.x >= 0 && uv.y >= 0 && uv.x < inputImageSize.x && uv.y < inputImageSize.y)
|
||||||
|
{
|
||||||
|
return imageLoad(inputImage, uv).rgb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//two extra row/col
|
||||||
|
shared vec3 sData[16 + 2][16 + 2];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// convenient variables
|
||||||
|
ivec3 globalThread = ivec3(gl_GlobalInvocationID);
|
||||||
|
ivec3 localThread = ivec3(gl_LocalInvocationID);
|
||||||
|
ivec2 inputImageSize = imageSize(inputImage);
|
||||||
|
|
||||||
|
// load shared memory
|
||||||
|
ivec2 start = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize) - ivec2(HALF_M_WIDTH);
|
||||||
|
for (int i = localThread.x; i < SHM_WIDTH; i += int(gl_WorkGroupSize.x))
|
||||||
|
{
|
||||||
|
for (int j = localThread.y; j < SHM_WIDTH; j += int(gl_WorkGroupSize.y))
|
||||||
|
{
|
||||||
|
// get from source image (either real values or 0)
|
||||||
|
vec3 sourceValue = GetImageValues(start + ivec2(i, j), inputImageSize);
|
||||||
|
sData[i][j] = sourceValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for shared memory to finish loading
|
||||||
|
barrier();
|
||||||
|
|
||||||
|
// max (between all 8 masks)
|
||||||
|
vec3 maxSum = vec3(0.0f);
|
||||||
|
|
||||||
|
// loop through all masks
|
||||||
|
for (int i = 0; i < NUM_MASKS; ++i)
|
||||||
|
{
|
||||||
|
vec3 sum = vec3(0.0f);
|
||||||
|
|
||||||
|
// start of shared memory
|
||||||
|
ivec2 shmStart = ivec2(localThread + HALF_M_WIDTH);
|
||||||
|
for (int j = -1; j < HALF_M_WIDTH + 1; ++j)
|
||||||
|
{
|
||||||
|
for (int k = -1; k < HALF_M_WIDTH + 1; ++k)
|
||||||
|
{
|
||||||
|
// Perform convolution using shared_memory
|
||||||
|
sum += sData[shmStart.x + j][shmStart.y + k] * kirsch[i][j + 1][k + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get highest sum
|
||||||
|
maxSum = max(sum, maxSum);
|
||||||
|
}
|
||||||
|
|
||||||
|
// average the max sum
|
||||||
|
maxSum = min(max(maxSum / 8, 0), 1.0f);
|
||||||
|
|
||||||
|
// store result into result image
|
||||||
|
imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(maxSum, 1.0f));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue