Merge remote-tracking branch 'origin/main' into SP3-2-Physics

This commit is contained in:
Diren D Bharwani 2022-11-08 15:22:28 +08:00
commit f8417f6116
41 changed files with 495 additions and 153 deletions

View File

@ -226,23 +226,4 @@
Color: {x: 1, y: 1, z: 1, w: 1} Color: {x: 1, y: 1, z: 1, w: 1}
Layer: 4294967295 Layer: 4294967295
Strength: 0.25 Strength: 0.25
Scripts: ~
- EID: 10
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: 2.45315814, z: -5}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 2, y: 1, z: 1}
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 2, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~ Scripts: ~

View File

@ -501,9 +501,12 @@ namespace SHADE
ImGui_ImplVulkan_DestroyFontUploadObjects(); ImGui_ImplVulkan_DestroyFontUploadObjects();
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) { renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd)
{
cmd->BeginLabeledSegment("ImGui Draw");
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
}); cmd->EndLabeledSegment();
});
#endif #endif
} }

View File

@ -288,7 +288,7 @@ namespace SHADE
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered) bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered) if (isHovered)
@ -296,7 +296,7 @@ namespace SHADE
ImGui::SameLine(); ImGui::SameLine();
SHEntity* entity = SHEntityManager::GetEntityByID(value); SHEntity* entity = SHEntityManager::GetEntityByID(value);
std::ostringstream oss; std::ostringstream oss;
if (entity) if (!alwaysNull && entity)
{ {
oss << value << ": " << entity->name; oss << value << ": " << entity->name;
} }
@ -314,6 +314,13 @@ namespace SHADE
SHDragDrop::EndTarget(); SHDragDrop::EndTarget();
} }
} }
ImGui::SameLine();
if (ImGui::Button("Clear"))
{
value = MAX_EID;
changed = true;
}
return changed; return changed;
} }

View File

@ -313,8 +313,12 @@ namespace SHADE
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param> /// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <param name="alwaysNull>
/// If set, the field displayed will always be blank regardless of specified
/// GameObject.
/// </param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr); static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr, bool alwaysNull = false);
/// <summary> /// <summary>
/// Creates a combo box for enumeration input. /// Creates a combo box for enumeration input.
/// </summary> /// </summary>

View File

@ -217,9 +217,11 @@ namespace SHADE
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?) &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?)
&allocCreateInfo, &allocCreateInfo,
&tempBuffer, &stagingAlloc, &allocInfo); &tempBuffer, &stagingAlloc, &allocInfo);
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging - " + name);
// then assign it to the hpp version // then assign it to the hpp version
stagingBuffer = tempBuffer; stagingBuffer = tempBuffer;
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, stagingBuffer, "[Buffer] Staging - " + name);
// Just map, copy then unmap // Just map, copy then unmap
void* stagingBufferMappedPtr = nullptr; void* stagingBufferMappedPtr = nullptr;
@ -251,7 +253,11 @@ namespace SHADE
auto result = vmaCreateBuffer(vmaAllocator, auto result = vmaCreateBuffer(vmaAllocator,
&bufferCreateInfo.operator VkBufferCreateInfo & (), &bufferCreateInfo.operator VkBufferCreateInfo & (),
&allocCreateInfo, &allocCreateInfo,
&tempBuffer, &alloc, &allocInfo); &tempBuffer, &alloc, &allocInfo);
#ifdef _DEBUG
if (!name.empty())
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] " + name);
#endif
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. "); SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. ");
@ -269,7 +275,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHVkBuffer::SHVkBuffer(std::reference_wrapper<VmaAllocator const> allocator) noexcept SHVkBuffer::SHVkBuffer(Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept
: vkBuffer{} : vkBuffer{}
, stagingBuffer{} , stagingBuffer{}
, sizeStored{ 0 } , sizeStored{ 0 }
@ -277,19 +283,23 @@ namespace SHADE
, alloc {nullptr} , alloc {nullptr}
, randomAccessOptimized{false} , randomAccessOptimized{false}
, vmaAllocator{allocator} , vmaAllocator{allocator}
, device { logicalDevice }
{} {}
SHVkBuffer::SHVkBuffer( SHVkBuffer::SHVkBuffer(
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize, uint32_t inSize,
void* data, void* data,
uint32_t srcSize, uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> allocator, std::reference_wrapper<VmaAllocator const> allocator,
vk::BufferUsageFlags bufferUsage, vk::BufferUsageFlags bufferUsage,
const std::string& name,
VmaMemoryUsage memUsage, VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags VmaAllocationCreateFlags allocFlags
) noexcept ) noexcept
: SHVkBuffer(allocator) : SHVkBuffer(logicalDevice, allocator)
{ {
this->name = name;
Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags); Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags);
} }
@ -304,6 +314,8 @@ namespace SHADE
, bufferUsageFlags {rhs.bufferUsageFlags} , bufferUsageFlags {rhs.bufferUsageFlags}
, bufferCreateInfo { rhs.bufferCreateInfo } , bufferCreateInfo { rhs.bufferCreateInfo }
, allocCreateInfo { rhs.allocCreateInfo } , allocCreateInfo { rhs.allocCreateInfo }
, name { std::move(rhs.name) }
, device { rhs.device }
{ {
rhs.vkBuffer = VK_NULL_HANDLE; rhs.vkBuffer = VK_NULL_HANDLE;
@ -325,6 +337,8 @@ namespace SHADE
bufferCreateInfo = rhs.bufferCreateInfo; bufferCreateInfo = rhs.bufferCreateInfo;
allocCreateInfo = rhs.allocCreateInfo; allocCreateInfo = rhs.allocCreateInfo;
bufferUsageFlags = rhs.bufferUsageFlags; bufferUsageFlags = rhs.bufferUsageFlags;
name = std::move(rhs.name);
device = rhs.device;
return *this; return *this;
} }
@ -402,6 +416,8 @@ namespace SHADE
auto [tempBuffer, allocInfo] = createBuffer(sizeStored); auto [tempBuffer, allocInfo] = createBuffer(sizeStored);
vkBuffer = tempBuffer; vkBuffer = tempBuffer;
if (!name.empty())
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, vkBuffer, "[Buffer] " + name);
// This probably means that a HOST_CACHED memory type is used on allocation // This probably means that a HOST_CACHED memory type is used on allocation
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)

View File

@ -12,6 +12,7 @@ namespace SHADE
//using SHVkBufferUsageBits = vk::BufferUsageFlagBits; //using SHVkBufferUsageBits = vk::BufferUsageFlagBits;
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHVkLogicalDevice;
class SHVkBuffer class SHVkBuffer
{ {
@ -51,6 +52,11 @@ namespace SHADE
//VmaAllocator const& vmaAllocator; //VmaAllocator const& vmaAllocator;
std::reference_wrapper<VmaAllocator const> vmaAllocator; std::reference_wrapper<VmaAllocator const> vmaAllocator;
//! Name of this buffer if any
std::string name;
//! Handle to the logical device that created this buffer
Handle<SHVkLogicalDevice> device;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -62,13 +68,15 @@ namespace SHADE
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHVkBuffer (void) noexcept = delete; SHVkBuffer (void) noexcept = delete;
SHVkBuffer (std::reference_wrapper<VmaAllocator const> allocator) noexcept; SHVkBuffer (Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept;
SHVkBuffer ( SHVkBuffer (
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize, uint32_t inSize,
void* data, void* data,
uint32_t srcSize, uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> allocator, std::reference_wrapper<VmaAllocator const> allocator,
vk::BufferUsageFlags bufferUsage, vk::BufferUsageFlags bufferUsage,
const std::string& name = "",
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlags allocFlags = {} VmaAllocationCreateFlags allocFlags = {}
) noexcept; ) noexcept;
@ -84,7 +92,7 @@ namespace SHADE
uint32_t inSize, uint32_t inSize,
void* data, void* data,
uint32_t srcSize, uint32_t srcSize,
vk::BufferUsageFlags bufferUsage, vk::BufferUsageFlags bufferUsage,
VmaMemoryUsage memUsage, VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags VmaAllocationCreateFlags allocFlags
) noexcept; ) noexcept;

View File

@ -105,6 +105,9 @@ namespace SHADE
// Set the state to recording if the call above succeeded. // Set the state to recording if the call above succeeded.
cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING; cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING;
// Reset segment count
segmentDepth = 0;
} }
/***************************************************************************/ /***************************************************************************/
@ -507,6 +510,41 @@ namespace SHADE
SetState(SH_CMD_BUFFER_STATE::PENDING); SetState(SH_CMD_BUFFER_STATE::PENDING);
} }
void SHVkCommandBuffer::BeginLabeledSegment(const std::string& label) noexcept
{
#ifdef _DEBUG
static const std::array SEGMENT_COLOURS =
{
SHColour::LIGHTPINK,
SHColour::LIGHTBLUE,
SHColour::LIGHTGREEN,
SHColour::YELLOW,
SHColour::PINK,
SHColour::TEAL,
SHColour::LIME,
SHColour::ORANGE,
SHColour::VIOLET,
SHColour::MAROON,
SHColour::DARKGREEN,
SHColour::SANDYBROWN
};
const SHColour COLOR = SEGMENT_COLOURS[segmentDepth];
++segmentDepth;
if (segmentDepth >= static_cast<int>(SEGMENT_COLOURS.size()))
segmentDepth = 0;
vkCommandBuffer.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT().setPLabelName(label.data()).setColor({ COLOR.x, COLOR.y, COLOR.z, COLOR.w }));
#endif
}
void SHVkCommandBuffer::EndLabeledSegment() noexcept
{
#ifdef _DEBUG
vkCommandBuffer.endDebugUtilsLabelEXT();
segmentDepth = std::max(segmentDepth - 1, 0);
#endif
}
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept //void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
//{ //{
// //vkCommandBuffer.pipelineBarrier() // //vkCommandBuffer.pipelineBarrier()

View File

@ -7,6 +7,7 @@
#include "Resource/SHResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/Pipeline/SHPipelineType.h" #include "Graphics/Pipeline/SHPipelineType.h"
#include "Math/SHColour.h"
namespace SHADE namespace SHADE
{ {
@ -78,7 +79,11 @@ namespace SHADE
std::array<PipelineBindPointData, static_cast<uint32_t>(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData; 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];
#ifdef _DEBUG
int segmentDepth;
#endif
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
@ -107,7 +112,7 @@ namespace SHADE
void Reset(void); void Reset(void);
// Begins and Ends // Begins and Ends
void BeginRecording (void) noexcept; void BeginRecording () noexcept;
void EndRecording (void) noexcept; void EndRecording (void) noexcept;
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept; void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
void EndRenderpass (void) noexcept; void EndRenderpass (void) noexcept;
@ -148,6 +153,10 @@ namespace SHADE
bool IsReadyToSubmit (void) const noexcept; bool IsReadyToSubmit (void) const noexcept;
void HandlePostSubmit (void) noexcept; void HandlePostSubmit (void) noexcept;
// Debugging
void BeginLabeledSegment(const std::string& label) noexcept;
void EndLabeledSegment() noexcept;
// Push Constant variable setting // Push Constant variable setting
template <typename T> template <typename T>
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept

View File

@ -220,6 +220,7 @@ namespace SHADE
else else
{ {
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. "); SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. ");
SET_VK_OBJ_NAME(this, vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device");
} }
InitializeVMA(); InitializeVMA();
@ -419,9 +420,9 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) const noexcept Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags, const std::string& name) const noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, memUsage, allocFlags); return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(GetHandle(), inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, name, memUsage, allocFlags);
} }
/***************************************************************************/ /***************************************************************************/
@ -455,12 +456,12 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, w, h, levels, format, usage, create); return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, w, h, levels, format, usage, create);
} }
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags); return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
} }
/***************************************************************************/ /***************************************************************************/

View File

@ -1,5 +1,4 @@
#ifndef SH_LOGICAL_DEVICE_H #pragma once
#define SH_LOGICAL_DEVICE_H
#include <optional> #include <optional>
#include <array> #include <array>
@ -67,7 +66,6 @@ namespace SHADE
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice> class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
{ {
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -147,7 +145,8 @@ namespace SHADE
uint32_t srcSize, uint32_t srcSize,
vk::BufferUsageFlags bufferUsage, vk::BufferUsageFlags bufferUsage,
VmaMemoryUsage memUsage, VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags VmaAllocationCreateFlags allocFlags,
const std::string& name = ""
) const noexcept; ) const noexcept;
Handle<SHVkImage> CreateImage ( Handle<SHVkImage> CreateImage (
@ -202,7 +201,33 @@ namespace SHADE
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept; Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept; void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
void UpdateDescriptorSet (vk::WriteDescriptorSet const& writeDescSet) noexcept; void UpdateDescriptorSet(vk::WriteDescriptorSet const& writeDescSet) noexcept;
/*-----------------------------------------------------------------------*/
/* Debug Tools */
/*-----------------------------------------------------------------------*/
#ifdef _DEBUG
/// <summary>
/// Sets a Vulkan HPP object's name for debugging purposes. This function will not be
/// compiled outside of Debug configurations. Hence, it is advised to use provided
/// macro function SET_VK_OBJ_NAME() instead of using this function directly.
/// </summary>
/// <param name="objType">Type of the object.</param>
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
/// <param name="objName">Object's name.</param>
template<typename T>
inline void SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName);
/// <summary>
/// Sets a Vulkan object's name for debugging purposes. This function will not be
/// compiled outside of Debug configurations. Hence, it is advised to use provided
/// macro function SET_VK_OBJ_NAME_VK() instead of using this function directly.
/// </summary>
/// <param name="objType">Type of the object.</param>
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
/// <param name="objName">Object's name.</param>
template<typename T>
inline void SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName);
#endif
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */
@ -220,4 +245,4 @@ namespace SHADE
}; };
} }
#endif #include "SHVkLogicalDevice.hpp"

View File

@ -0,0 +1,61 @@
/************************************************************************************//*!
\file SHVkLogicalDevice.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 4, 2022
\brief Contains implementation of inline and template functions of
SHVkLogicalDevice.
Copyright (C) 2022 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.
*//*************************************************************************************/
#pragma once
#include "SHVkLogicalDevice.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Debug Tools */
/*-----------------------------------------------------------------------------------*/
#ifdef _DEBUG
template<typename T>
void SHVkLogicalDevice::SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName)
{
if (objName.empty())
return;
vk::DebugUtilsObjectNameInfoEXT info;
info.objectType = objType;
info.objectHandle = (uint64_t) static_cast<typename T::NativeType>(objHandle);
info.pObjectName = objName.data();
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
}
template<typename T>
void SHVkLogicalDevice::SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName)
{
if (objName.empty())
return;
vk::DebugUtilsObjectNameInfoEXT info;
info.objectType = objType;
info.objectHandle = (uint64_t) objVkHandle;
info.pObjectName = objName.data();
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
}
#endif
}
/*-------------------------------------------------------------------------------------*/
/* Macro Definitions */
/*-------------------------------------------------------------------------------------*/
#ifdef _DEBUG
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
DEVICE->SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
DEVICE->SetVulkanObjectNameVk(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
#else
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
#endif

View File

@ -61,6 +61,7 @@ namespace SHADE
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?) &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
&allocCreateInfo, &allocCreateInfo,
&tempBuffer, &stagingAlloc, &allocInfo); &tempBuffer, &stagingAlloc, &allocInfo);
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging Buffer for Image");
// then assign it to the hpp version // then assign it to the hpp version
stagingBuffer = tempBuffer; stagingBuffer = tempBuffer;
@ -107,6 +108,8 @@ namespace SHADE
VkImage tempImage; VkImage tempImage;
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
vkImage = tempImage; vkImage = tempImage;
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
@ -115,7 +118,8 @@ namespace SHADE
} }
SHVkImage::SHVkImage( SHVkImage::SHVkImage(
VmaAllocator const* allocator, Handle<SHVkLogicalDevice> logicalDeviceHdl,
VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails, SHImageCreateParams const& imageDetails,
const unsigned char* data, const unsigned char* data,
uint32_t dataSize, uint32_t dataSize,
@ -137,6 +141,7 @@ namespace SHADE
, boundToCoherent{false} , boundToCoherent{false}
, randomAccessOptimized {false} , randomAccessOptimized {false}
, mappedPtr{nullptr} , mappedPtr{nullptr}
, device { logicalDeviceHdl }
{ {
usageFlags = imageDetails.usageFlags; usageFlags = imageDetails.usageFlags;
createFlags = imageDetails.createFlags; createFlags = imageDetails.createFlags;
@ -175,7 +180,9 @@ namespace SHADE
VmaAllocationInfo allocInfo{}; VmaAllocationInfo allocInfo{};
VkImage tempImage; VkImage tempImage;
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo); auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
@ -220,7 +227,7 @@ namespace SHADE
//} //}
} }
SHVkImage::SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept SHVkImage::SHVkImage(Handle<SHVkLogicalDevice> logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
: width {w} : width {w}
, height{h} , height{h}
, depth {1} , depth {1}
@ -230,11 +237,12 @@ namespace SHADE
, usageFlags{usage} , usageFlags{usage}
, createFlags {create} , createFlags {create}
, vmaAllocator {allocator} , vmaAllocator {allocator}
, device { logicalDeviceHdl }
{ {
CreateFramebufferImage(); CreateFramebufferImage();
} }
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams); return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
} }

View File

@ -104,6 +104,9 @@ namespace SHADE
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource //! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
std::span<uint32_t> mipOffsets; std::span<uint32_t> mipOffsets;
//! Handle to the device that creates these images
Handle<SHVkLogicalDevice> device;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -117,6 +120,7 @@ namespace SHADE
SHVkImage(void) noexcept = default; SHVkImage(void) noexcept = default;
SHVkImage( SHVkImage(
Handle<SHVkLogicalDevice> logicalDeviceHdl,
VmaAllocator const* allocator, VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails, SHImageCreateParams const& imageDetails,
const unsigned char* data, const unsigned char* data,
@ -126,7 +130,7 @@ namespace SHADE
VmaAllocationCreateFlags allocFlags VmaAllocationCreateFlags allocFlags
) noexcept; ) noexcept;
SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept; SHVkImage(Handle<SHVkLogicalDevice> logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
SHVkImage(SHVkImage&& rhs) noexcept = default; SHVkImage(SHVkImage&& rhs) noexcept = default;
SHVkImage& operator=(SHVkImage && rhs) noexcept = default; SHVkImage& operator=(SHVkImage && rhs) noexcept = default;
@ -134,7 +138,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept; Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept; void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept; void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;

View File

@ -392,20 +392,23 @@ namespace SHADE
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
BuffUsage::eIndirectBuffer BuffUsage::eIndirectBuffer,
"Batch Draw Data Buffer"
); );
// - Transform Buffer // - Transform Buffer
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)); const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Batch Transform Buffer"
); );
const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)); const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData));
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES, device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES,
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Batch Instance Data Buffer"
); );
// - Material Properties Buffer // - Material Properties Buffer
rebuildMaterialBuffers(frameIndex, descPool); rebuildMaterialBuffers(frameIndex, descPool);
@ -427,6 +430,7 @@ namespace SHADE
// Bind all required objects before drawing // Bind all required objects before drawing
static std::array<uint32_t, 1> dynamicOffset{ 0 }; static std::array<uint32_t, 1> dynamicOffset{ 0 };
cmdBuffer->BeginLabeledSegment("SHBatch");
cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindPipeline(pipeline);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
@ -441,6 +445,7 @@ namespace SHADE
); );
} }
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size())); cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
cmdBuffer->EndLabeledSegment();
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -460,7 +465,8 @@ namespace SHADE
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize), device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
vk::BufferUsageFlagBits::eStorageBuffer vk::BufferUsageFlagBits::eStorageBuffer,
"Batch Material Data"
); );
if (!matPropsDescSet[frameIndex]) if (!matPropsDescSet[frameIndex])
@ -470,6 +476,13 @@ namespace SHADE
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
{ 0 } { 0 }
); );
#ifdef _DEBUG
const auto& DESC_SETS = matPropsDescSet[frameIndex]->GetVkHandle();
for (auto descSet : DESC_SETS)
{
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, descSet, "[Descriptor Set] Batch Material Data");
}
#endif
} }
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] }; std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer matPropsDescSet[frameIndex]->ModifyWriteDescBuffer

View File

@ -13,14 +13,13 @@ namespace SHADE
/* Static Definitions */ /* Static Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts; std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
Handle<SHVkDescriptorSetGroup> SHGraphicsGlobalData::globalDescSets;
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState; SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout; Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept
{ {
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Function Definitions */ /* Function Definitions */
@ -45,7 +44,8 @@ namespace SHADE
}; };
// For global data (generic data and textures) // For global data (generic data and textures)
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding }); Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals");
std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{}; std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{};
@ -71,11 +71,11 @@ namespace SHADE
}); });
} }
// For Dynamic global data (lights) // For Dynamic global data (lights)
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings); Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings);
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, dynamicGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals");
// For High frequency global data (camera)
SHVkDescriptorSetLayout::Binding cameraDataBinding SHVkDescriptorSetLayout::Binding cameraDataBinding
{ {
.Type = vk::DescriptorType::eUniformBufferDynamic, .Type = vk::DescriptorType::eUniformBufferDynamic,
@ -83,10 +83,10 @@ namespace SHADE
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, .BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
.DescriptorCount = 1, .DescriptorCount = 1,
}; };
// For High frequency global data (camera)
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding }); Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals");
// For per instance data (transforms, materials, etc.)
SHVkDescriptorSetLayout::Binding materialDataBinding SHVkDescriptorSetLayout::Binding materialDataBinding
{ {
.Type = vk::DescriptorType::eStorageBufferDynamic, .Type = vk::DescriptorType::eStorageBufferDynamic,
@ -94,9 +94,8 @@ namespace SHADE
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, .BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
.DescriptorCount = 1, .DescriptorCount = 1,
}; };
// For High frequency global data (camera)
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding }); Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
globalDescSetLayouts.push_back(staticGlobalLayout); globalDescSetLayouts.push_back(staticGlobalLayout);
globalDescSetLayouts.push_back(dynamicGlobalLayout); globalDescSetLayouts.push_back(dynamicGlobalLayout);

View File

@ -17,9 +17,6 @@ namespace SHADE
//! Global descriptor set layouts. Used to allocate descriptor sets //! Global descriptor set layouts. Used to allocate descriptor sets
static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts; static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
//! Global Descriptor sets
static Handle<SHVkDescriptorSetGroup> globalDescSets;
//! Default vertex input state (used by everything). //! Default vertex input state (used by everything).
static SHVertexInputState defaultVertexInputState; static SHVertexInputState defaultVertexInputState;

View File

@ -98,6 +98,7 @@ namespace SHADE
// Don't draw if no points // Don't draw if no points
if (numPoints[FRAME_IDX] > 0) if (numPoints[FRAME_IDX] > 0)
{ {
cmdBuffer->BeginLabeledSegment("SHDebugDraw");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline()); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
@ -113,10 +114,12 @@ namespace SHADE
// Don't draw if no points // Don't draw if no points
if (numPersistentPoints[FRAME_IDX] > 0) if (numPersistentPoints[FRAME_IDX] > 0)
{ {
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline()); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0); cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0); cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
cmdBuffer->EndLabeledSegment();
} }
}); });
@ -138,7 +141,8 @@ namespace SHADE
0, 0,
vk::BufferUsageFlagBits::eVertexBuffer, vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Debug Draw Non-Persistent Vertex Buffer"
); );
} }
// - Persistent Draws // - Persistent Draws
@ -151,7 +155,8 @@ namespace SHADE
0, 0,
vk::BufferUsageFlagBits::eVertexBuffer, vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Debug Draw Persistent Vertex Buffer"
); );
} }
} }

View File

@ -1,5 +1,5 @@
/************************************************************************************//*! /************************************************************************************//*!
\file SHGraphicsSystem.cpp \file SHGrphicsSystem.cpp
\author Tng Kah Wei, kahwei.tng, 390009620 \author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Aug 21, 2022 \date Aug 21, 2022
@ -165,7 +165,7 @@ namespace SHADE
/* SCENE RENDER GRAPH RESOURCES */ /* SCENE RENDER GRAPH RESOURCES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Initialize world render graph // Initialize world render graph
worldRenderGraph->Init(device, swapchain); worldRenderGraph->Init("World Render Graph", device, swapchain);
worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
@ -213,6 +213,7 @@ namespace SHADE
ssaoStorage = resourceManager.Create<SHSSAO>(); ssaoStorage = resourceManager.Create<SHSSAO>();
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)");
ssaoTransferCmdBuffer->BeginRecording(); ssaoTransferCmdBuffer->BeginRecording();
ssaoStorage->Init(device, ssaoTransferCmdBuffer); ssaoStorage->Init(device, ssaoTransferCmdBuffer);
@ -234,7 +235,7 @@ namespace SHADE
ssaoStorage->PrepareRotationVectorsVkData(device); ssaoStorage->PrepareRotationVectorsVkData(device);
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"}); Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" });
auto ssaoDataBuffer = ssaoStorage->GetBuffer(); auto ssaoDataBuffer = ssaoStorage->GetBuffer();
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored()); ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout(); auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
@ -242,12 +243,12 @@ namespace SHADE
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1}); ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"}); Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, {"SSAO", "SSAO Blur"});
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* DEFERRED COMPOSITE SUBPASS INIT */ /* DEFERRED COMPOSITE SUBPASS INIT */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"});
// Dummy Node // Dummy Node
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
@ -271,7 +272,11 @@ namespace SHADE
// Create debug draw pipeline // Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass); debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Pipeline Layout");
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test Pipeline Layout");
} }
void SHGraphicsSystem::InitMiddleEnd(void) noexcept void SHGraphicsSystem::InitMiddleEnd(void) noexcept
@ -350,7 +355,7 @@ namespace SHADE
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
editorRenderGraph->Init(device, swapchain); editorRenderGraph->Init("Editor Render Graph", device, swapchain);
editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
@ -677,6 +682,8 @@ namespace SHADE
auto renderGraphNode = subpass->GetParentNode(); auto renderGraphNode = subpass->GetParentNode();
auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass); auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, pipeline->GetVkPipeline(), "[Pipeline] Custom Pipeline");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, pipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Custom Pipeline Layout");
mat->SetPipeline(pipeline); mat->SetPipeline(pipeline);
@ -723,14 +730,15 @@ namespace SHADE
void SHGraphicsSystem::BuildMeshBuffers() void SHGraphicsSystem::BuildMeshBuffers()
{ {
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
device->WaitIdle(); SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, transferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Mesh Buffer Building (Transfer)");
device->WaitIdle();
transferCmdBuffer->BeginRecording(); transferCmdBuffer->BeginRecording();
meshLibrary.BuildBuffers(device, transferCmdBuffer); meshLibrary.BuildBuffers(device, transferCmdBuffer);
transferCmdBuffer->EndRecording(); transferCmdBuffer->EndRecording();
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer }); graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
device->WaitIdle(); device->WaitIdle();
transferCmdBuffer.Free(); transferCmdBuffer = {}; transferCmdBuffer.Free(); transferCmdBuffer = {};
} }
Handle<SHMesh> SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept Handle<SHMesh> SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept
@ -750,14 +758,18 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset) Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
{ {
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) }); const int MIPS = texAsset.mipOffsets.size();
return texLibrary.Add(texAsset, sampler); auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(MIPS) });
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
return texLibrary.Add(texAsset, sampler);
} }
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets) SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
{ {
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) }); const int MIPS = mipOffsets.size();
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler); auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(MIPS) });
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
} }
void SHGraphicsSystem::RemoveTexture(Handle<SHTexture> tex) void SHGraphicsSystem::RemoveTexture(Handle<SHTexture> tex)
@ -768,6 +780,7 @@ namespace SHADE
void SHGraphicsSystem::BuildTextures() void SHGraphicsSystem::BuildTextures()
{ {
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, graphicsTexCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Texture Building (Graphics)");
device->WaitIdle(); device->WaitIdle();
texLibrary.BuildTextures texLibrary.BuildTextures
( (

View File

@ -165,35 +165,40 @@ namespace SHADE
device, cmdBuffer, vertPosBuffer, device, cmdBuffer, vertPosBuffer,
vertPosStorage.data(), vertPosStorage.data(),
static_cast<uint32_t>(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition), static_cast<uint32_t>(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex Positions"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, vertTexCoordBuffer, device, cmdBuffer, vertTexCoordBuffer,
vertTexCoordStorage.data(), vertTexCoordStorage.data(),
static_cast<uint32_t>(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord), static_cast<uint32_t>(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex TexCoords"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, vertTangentBuffer, device, cmdBuffer, vertTangentBuffer,
vertTangentStorage.data(), vertTangentStorage.data(),
static_cast<uint32_t>(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent), static_cast<uint32_t>(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex Tangents"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, vertNormalBuffer, device, cmdBuffer, vertNormalBuffer,
vertNormalStorage.data(), vertNormalStorage.data(),
static_cast<uint32_t>(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal), static_cast<uint32_t>(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex Normals"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, indexBuffer, device, cmdBuffer, indexBuffer,
indexStorage.data(), indexStorage.data(),
static_cast<uint32_t>(indexStorage.size()) * sizeof(SHMesh::Index), static_cast<uint32_t>(indexStorage.size()) * sizeof(SHMesh::Index),
BuffUsage::eIndexBuffer BuffUsage::eIndexBuffer,
"Mesh Library Indices"
); );
isDirty = false; isDirty = false;

View File

@ -76,7 +76,7 @@ namespace SHADE
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// Create the buffer // Create the buffer
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Mouse Pick Image Data Destination");
} }
void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept

View File

@ -39,9 +39,15 @@ namespace SHADE
cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 });
#ifdef _DEBUG
const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle();
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i)
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Camera Data Frame #" + std::to_string(i));
#endif
cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData));
cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Camera Data");
std::array cameraBufferArray{cameraBuffer}; std::array cameraBufferArray{cameraBuffer};

View File

@ -134,7 +134,7 @@ namespace SHADE
lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights); lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights);
// We want to initialize 3 times the amount of data required. // We want to initialize 3 times the amount of data required.
dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Data");
} }
else else
{ {
@ -385,8 +385,12 @@ namespace SHADE
std::fill (variableSizes.begin(), variableSizes.end(), 1); std::fill (variableSizes.begin(), variableSizes.end(), 1);
// Create the descriptor set // Create the descriptor set
lightingDataDescSet = descPool->Allocate({SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS]}, variableSizes); lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes);
#ifdef _DEBUG
const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle();
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i)
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Light Data Frame #" + std::to_string(i));
#endif
for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i) for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i)
{ {
@ -402,7 +406,7 @@ namespace SHADE
lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize); lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize);
// Create the GPU buffer to hold light count // Create the GPU buffer to hold light count
lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Count Data");
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES); lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES);
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT); lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT);

View File

@ -26,7 +26,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHPerFrameData::Recreate(Handle<SHVkLogicalDevice> const& logicalDeviceHdl) noexcept void SHPerFrameData::Recreate(Handle<SHVkLogicalDevice> logicalDeviceHdl) noexcept
{ {
// Swapchain recreation means the images are just relinked to SHVkImages. Handles will remain the same. There is no need for this line. // Swapchain recreation means the images are just relinked to SHVkImages. Handles will remain the same. There is no need for this line.
//swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex); //swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex);
@ -44,14 +44,17 @@ namespace SHADE
// Create image views for the swapchain // Create image views for the swapchain
swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails); swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails);
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eImageView, swapchainImageViewHdl->GetImageView(), "[Image View] Swap Chain");
// Create a fence // Create a fence
fenceHdl = logicalDeviceHdl->CreateFence(); fenceHdl = logicalDeviceHdl->CreateFence();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eFence, fenceHdl->GetVkFence(), "[Fence] Swap Chain");
// scope makes it easier to navigate // scope makes it easier to navigate
semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semImgAvailableHdl->GetVkSem(), "[Semaphore] Swap Chain Image Available");
semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semRenderFinishHdl->GetVkSem(), "[Semaphore] Swap Chain Render Finish");
} }
/***************************************************************************/ /***************************************************************************/

View File

@ -63,7 +63,7 @@ namespace SHADE
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// These are made into functions (instead of ctor and dtor) because we want to call these functions again when we resize the window // These are made into functions (instead of ctor and dtor) because we want to call these functions again when we resize the window
void Recreate (Handle<SHVkLogicalDevice> const& logicalDeviceHdl) noexcept; void Recreate (Handle<SHVkLogicalDevice> logicalDeviceHdl) noexcept;
void Destroy (void); void Destroy (void);
friend class SHRenderContext; friend class SHRenderContext;

View File

@ -50,7 +50,13 @@ namespace SHADE
for (uint32_t j = 0; j < params.numThreads; ++j) for (uint32_t j = 0; j < params.numThreads; ++j)
{ {
frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient)); auto cmdPool = logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient);
SET_VK_OBJ_NAME
(
logicalDeviceHdl, vk::ObjectType::eCommandPool, cmdPool->GetVkCommandPool(),
"[Command Pool] Render Context #" + std::to_string(i) + " Pool #" + std::to_string(j)
);
frameData[i].cmdPoolHdls.push_back(cmdPool);
} }
} }

View File

@ -23,6 +23,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/Images/SHVkImage.h" #include "Graphics/Images/SHVkImage.h"
#include "Graphics/Images/SHVkImageView.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Assets/Asset Types/SHTextureAsset.h" #include "Assets/Asset Types/SHTextureAsset.h"
@ -78,6 +79,7 @@ namespace SHADE
{ {
job.Image = resourceManager.Create<SHVkImage> job.Image = resourceManager.Create<SHVkImage>
( (
device,
&device->GetVMAAllocator(), &device->GetVMAAllocator(),
SHImageCreateParams SHImageCreateParams
{ {
@ -142,6 +144,7 @@ namespace SHADE
.layerCount = 1 .layerCount = 1
}; };
job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS); job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
} }
// Add Textures // Add Textures
@ -150,6 +153,9 @@ namespace SHADE
texOrder.emplace_back(job.TextureHandle); texOrder.emplace_back(job.TextureHandle);
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal)); combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U; job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U;
SET_VK_OBJ_NAME(device, vk::ObjectType::eImage, job.Image->GetVkImage(), "[Image] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
} }
addJobs.clear(); addJobs.clear();
@ -165,6 +171,10 @@ namespace SHADE
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
{ static_cast<uint32_t>(texOrder.size()) } { static_cast<uint32_t>(texOrder.size()) }
); );
#ifdef _DEBUG
for (auto set : texDescriptors->GetVkHandle())
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
#endif
texDescriptors->ModifyWriteDescImage texDescriptors->ModifyWriteDescImage
( (
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,

View File

@ -59,7 +59,8 @@ namespace SHADE
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
} }
renderGraphStorage->graphResources->try_emplace(resourceName, resourceManager->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); auto resource = resourceManager->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
} }
/***************************************************************************/ /***************************************************************************/
@ -353,7 +354,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHRenderGraph::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept void SHRenderGraph::Init(std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept
{ {
resourceManager = std::make_shared<SHResourceHub>(); resourceManager = std::make_shared<SHResourceHub>();
@ -365,6 +366,8 @@ namespace SHADE
renderGraphStorage->resourceManager = resourceManager; renderGraphStorage->resourceManager = resourceManager;
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
name = std::move(graphName);
} }
/***************************************************************************/ /***************************************************************************/
@ -390,6 +393,7 @@ namespace SHADE
, nodeIndexing{ std::move(rhs.nodeIndexing) } , nodeIndexing{ std::move(rhs.nodeIndexing) }
, nodes{ std::move(rhs.nodes) } , nodes{ std::move(rhs.nodes) }
, resourceManager{ std::move(rhs.resourceManager) } , resourceManager{ std::move(rhs.resourceManager) }
, name { std::move(rhs.name) }
{ {
} }
@ -403,6 +407,7 @@ namespace SHADE
nodeIndexing = std::move(rhs.nodeIndexing); nodeIndexing = std::move(rhs.nodeIndexing);
nodes = std::move(rhs.nodes); nodes = std::move(rhs.nodes);
resourceManager = std::move(rhs.resourceManager); resourceManager = std::move(rhs.resourceManager);
name = std::move(rhs.name);
return *this; return *this;
} }
@ -467,9 +472,9 @@ namespace SHADE
} }
} }
nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors))); auto node = nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u); nodeIndexing.emplace(std::move(nodeName), static_cast<uint32_t>(nodes.size()) - 1u);
return nodes.at(nodeIndexing[nodeName]); return node;
} }
/***************************************************************************/ /***************************************************************************/
@ -516,8 +521,10 @@ namespace SHADE
// 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
{ {
cmdBuffer->BeginLabeledSegment(name);
for (auto& node : nodes) for (auto& node : nodes)
node->Execute(cmdBuffer, descPool, frameIndex); node->Execute(cmdBuffer, descPool, frameIndex);
cmdBuffer->EndLabeledSegment();
} }
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)

View File

@ -69,6 +69,9 @@ namespace SHADE
//! Resource library for graph handles //! Resource library for graph handles
std::shared_ptr<SHResourceHub> resourceManager; std::shared_ptr<SHResourceHub> resourceManager;
//! Name of the RenderGraph
std::string name;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
@ -81,7 +84,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain) noexcept; void Init (std::string graphName, 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;

View File

@ -25,6 +25,7 @@ namespace SHADE
void SHRenderGraphNode::CreateRenderpass(void) noexcept void SHRenderGraphNode::CreateRenderpass(void) noexcept
{ {
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
} }
/***************************************************************************/ /***************************************************************************/
@ -57,6 +58,7 @@ namespace SHADE
framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight); framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
} }
} }
@ -116,7 +118,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHRenderGraphNode::SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept SHRenderGraphNode::SHRenderGraphNode(std::string nodeName, Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept
: graphStorage{ renderGraphStorage} : graphStorage{ renderGraphStorage}
, renderpass{} , renderpass{}
, framebuffers{} , framebuffers{}
@ -128,6 +130,7 @@ namespace SHADE
, executed{ false } , executed{ false }
, configured{ false } , configured{ false }
, nodeComputes{} , nodeComputes{}
, name { std::move(nodeName) }
{ {
// pipeline library initialization // pipeline library initialization
pipelineLibrary.Init(graphStorage->logicalDevice); pipelineLibrary.Init(graphStorage->logicalDevice);
@ -189,6 +192,7 @@ namespace SHADE
, 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) } , nodeComputes{ std::move(rhs.nodeComputes) }
, name { std::move(rhs.name) }
{ {
rhs.renderpass = {}; rhs.renderpass = {};
@ -213,7 +217,7 @@ namespace SHADE
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); nodeComputes = std::move(rhs.nodeComputes);
name = std::move(rhs.name);
rhs.renderpass = {}; rhs.renderpass = {};
@ -263,7 +267,7 @@ namespace SHADE
return subpass; return subpass;
} }
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept
{ {
// Look for the required resources in the graph // Look for the required resources in the graph
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{}; std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
@ -276,7 +280,7 @@ namespace SHADE
} }
// Create the subpass compute with the resources // Create the subpass compute with the resources
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty()); auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
nodeComputes.push_back(nodeCompute); nodeComputes.push_back(nodeCompute);
return nodeCompute; return nodeCompute;

View File

@ -78,8 +78,11 @@ namespace SHADE
//! Whether or not the node has been configured already or not //! Whether or not the node has been configured already or not
bool configured; bool configured;
//! Manages batching for this RenderPass
SHBatcher batcher; SHBatcher batcher;
//! Name of this node
std::string name;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
@ -92,7 +95,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept; SHRenderGraphNode(std::string nodeName, 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;
@ -100,7 +103,7 @@ 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, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
void AddDummySubpassIfNeeded (void) noexcept; void AddDummySubpassIfNeeded (void) noexcept;
// TODO: RemoveSubpass() // TODO: RemoveSubpass()

View File

@ -13,7 +13,7 @@
namespace SHADE namespace SHADE
{ {
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
: computePipeline{} : computePipeline{}
, pipelineLayout{} , pipelineLayout{}
, resources{} , resources{}
@ -22,6 +22,7 @@ namespace SHADE
, followingEndRenderpass {followingEndRP} , followingEndRenderpass {followingEndRP}
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
, computeResource{} , computeResource{}
, name { std::move(nodeName) }
{ {
SHPipelineLayoutParams pipelineLayoutParams SHPipelineLayoutParams pipelineLayoutParams
{ {
@ -31,13 +32,15 @@ namespace SHADE
}; };
// Create pipeline layout from parameters // Create pipeline layout from parameters
pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout(pipelineLayoutParams);
// Create the compute pipeline // Create the compute pipeline
computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout);
// and construct it // and construct it
computePipeline->ConstructPipeline(); computePipeline->ConstructPipeline();
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipelineLayout, pipelineLayout->GetVkPipelineLayout(), "[Compute Pipeline Layout] " + name);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipeline, computePipeline->GetVkPipeline(), "[Compute Pipeline] " + name);
// save the resources // save the resources
resources = std::move (subpassComputeResources); resources = std::move (subpassComputeResources);
@ -50,6 +53,10 @@ namespace SHADE
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
{ {
graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 }); graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 });
#ifdef _DEBUG
for (auto set : graphResourceDescSets[i]->GetVkHandle())
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " #" + std::to_string(i));
#endif
} }
@ -61,6 +68,10 @@ namespace SHADE
computeResource = graphStorage->resourceManager->Create<ComputeResource>(); computeResource = graphStorage->resourceManager->Create<ComputeResource>();
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE]; auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 }); computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
#ifdef _DEBUG
for (auto set : computeResource->descSet->GetVkHandle())
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
#endif
// Allocate for descriptor offsets // Allocate for descriptor offsets
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)

View File

@ -65,8 +65,11 @@ namespace SHADE
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers; std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
//! Name of this node
std::string name;
public: public:
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept; SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept; void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void HandleResize (void) noexcept; void HandleResize (void) noexcept;

View File

@ -82,6 +82,7 @@ namespace SHADE
{ {
images[i] = graphStorage->swapchain->GetSwapchainImage(i); images[i] = graphStorage->swapchain->GetSwapchainImage(i);
imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails); imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageViews[i]->GetImageView(), "[Image View] " + resourceName + " #" + std::to_string(i));
} }
} }
else // if swapchain image resource else // if swapchain image resource
@ -129,7 +130,9 @@ 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(graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); auto image = graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImage, image->GetVkImage(), "[Image] " + resourceName);
images.push_back(image);
// prepare image view details // prepare image view details
SHImageViewDetails viewDetails SHImageViewDetails viewDetails
@ -144,7 +147,9 @@ namespace SHADE
}; };
// just 1 image view created // just 1 image view created
imageViews.push_back(images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails)); auto imageView = images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails);
imageViews.push_back(imageView);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageView->GetImageView(), "[Image View] " + resourceName);
} }
} }

View File

@ -201,6 +201,7 @@ namespace SHADE
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
{ {
commandBuffer->BeginLabeledSegment(name);
// Ensure correct transforms are provided // Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex, descPool); superBatch->UpdateBuffers(frameIndex, descPool);
@ -212,7 +213,7 @@ namespace SHADE
{ {
drawCall(commandBuffer); drawCall(commandBuffer);
} }
commandBuffer->EndLabeledSegment();
} }
void SHSubpass::HandleResize(void) noexcept void SHSubpass::HandleResize(void) noexcept
@ -301,6 +302,11 @@ namespace SHADE
group.Free(); group.Free();
group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts);
#ifdef _DEBUG
const auto& GROUP_HANDLES = group->GetVkHandle();
for (int i = 0; i < static_cast<int>(GROUP_HANDLES.size()); ++i)
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, GROUP_HANDLES[i], "[Descriptor Set] " + name + " #" + std::to_string(i));
#endif
uint32_t i = 0; uint32_t i = 0;
for (auto& binding : bindings) for (auto& binding : bindings)

View File

@ -82,7 +82,7 @@ namespace SHADE
} }
} }
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, const std::string& name)
{ {
if (bufferHandle) if (bufferHandle)
{ {
@ -100,7 +100,8 @@ namespace SHADE
size, size,
usage | BuffUsage::eTransferDst, usage | BuffUsage::eTransferDst,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
name
); );
} }
@ -108,7 +109,7 @@ namespace SHADE
bufferHandle->TransferToDeviceResource(cmdBuffer); bufferHandle->TransferToDeviceResource(cmdBuffer);
} }
void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name)
{ {
if (bufferHandle) if (bufferHandle)
{ {
@ -126,7 +127,8 @@ namespace SHADE
size, size,
usage, usage,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
name
); );
} }
} }

View File

@ -54,7 +54,7 @@ namespace SHADE
*/ */
/***********************************************************************************/ /***********************************************************************************/
static void EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); static void EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = "");
/***********************************************************************************/ /***********************************************************************************/
/*! /*!
@ -80,7 +80,7 @@ namespace SHADE
*/ */
/***********************************************************************************/ /***********************************************************************************/
static void EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); static void EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = "");
static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept; static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept;
}; };

View File

@ -290,9 +290,14 @@ namespace SHADE
{ {
GameObject gameObj = safe_cast<GameObject>(field->GetValue(object)); GameObject gameObj = safe_cast<GameObject>(field->GetValue(object));
uint32_t entityId = gameObj.GetEntity(); uint32_t entityId = gameObj.GetEntity();
if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered)) if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered, !gameObj))
{ {
GameObject newVal = GameObject(entityId); GameObject newVal = GameObject(entityId);
if (entityId != MAX_EID)
{
// Null GameObject set
newVal = GameObject(entityId);
}
field->SetValue(object, newVal); field->SetValue(object, newVal);
registerUndoAction(object, field, newVal, gameObj); registerUndoAction(object, field, newVal, gameObj);
} }

View File

@ -6,9 +6,9 @@
\brief Contains the definition of the functions for the GameObject managed class. \brief Contains the definition of the functions for the GameObject managed class.
Note: This file is written in C++17/CLI. Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology. Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Headers // Precompiled Headers
@ -36,10 +36,12 @@ namespace SHADE
void GameObject::Destroy(GameObject obj) void GameObject::Destroy(GameObject obj)
{ {
if (!obj.valid)
throw gcnew System::NullReferenceException("Attempted to destroy a null GameObject.");
SHEntityManager::DestroyEntity(static_cast<EntityID>(obj.GetEntity())); SHEntityManager::DestroyEntity(static_cast<EntityID>(obj.GetEntity()));
} }
System::Nullable<GameObject> GameObject::Find(System::String ^ name) System::Nullable<GameObject> GameObject::Find(System::String^ name)
{ {
// Search the GameObjectLibrary for an Entity with the specified name // Search the GameObjectLibrary for an Entity with the specified name
const auto ENTITY_ID = SHEntityManager::GetEntityByName(Convert::ToNative(name)); const auto ENTITY_ID = SHEntityManager::GetEntityByName(Convert::ToNative(name));
@ -50,21 +52,27 @@ namespace SHADE
return GameObject(ENTITY_ID); return GameObject(ENTITY_ID);
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Properties */ /* Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
System::String^ GameObject::Name::get() System::String^ GameObject::Name::get()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return Convert::ToCLI(GetNativeEntity().name); return Convert::ToCLI(GetNativeEntity().name);
} }
bool GameObject::IsActiveSelf::get() bool GameObject::IsActiveSelf::get()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return GetNativeEntity().GetActive(); return GetNativeEntity().GetActive();
} }
bool GameObject::IsActiveInHierarchy::get() bool GameObject::IsActiveInHierarchy::get()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity()); auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity());
if (!node) if (!node)
{ {
@ -75,39 +83,49 @@ namespace SHADE
} }
Entity GameObject::EntityId::get() Entity GameObject::EntityId::get()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return entity; return entity;
} }
GameObject^ GameObject::Parent::get() GameObject^ GameObject::Parent::get()
{ {
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); if (!valid)
const auto* ROOT = SCENE_GRAPH.GetRoot(); throw gcnew System::NullReferenceException();
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
const auto* ROOT = SCENE_GRAPH.GetRoot();
const auto* NODE = SCENE_GRAPH.GetNode(entity); const auto* NODE = SCENE_GRAPH.GetNode(entity);
if (NODE == nullptr) if (NODE == nullptr)
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString()); throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
const auto* PARENT = NODE->GetParent(); const auto* PARENT = NODE->GetParent();
return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr; return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr;
} }
void GameObject::Parent::set(GameObject^ newParent) void GameObject::Parent::set(GameObject^ newParent)
{ {
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); if (!valid)
throw gcnew System::NullReferenceException();
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
if (newParent == nullptr) if (newParent == nullptr)
SCENE_GRAPH.SetParent(entity, nullptr); SCENE_GRAPH.SetParent(entity, nullptr);
else else
SCENE_GRAPH.SetParent(entity, newParent->EntityId); SCENE_GRAPH.SetParent(entity, newParent->EntityId);
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* GameObject Property Functions */ /* GameObject Property Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void GameObject::SetName(System::String^ name) void GameObject::SetName(System::String^ name)
{ {
if (!valid)
throw gcnew System::NullReferenceException();
GetNativeEntity().name = Convert::ToNative(name); GetNativeEntity().name = Convert::ToNative(name);
} }
void GameObject::SetActive(bool active) void GameObject::SetActive(bool active)
{ {
if (!valid)
throw gcnew System::NullReferenceException();
GetNativeEntity().SetActive(active); GetNativeEntity().SetActive(active);
} }
@ -117,63 +135,83 @@ namespace SHADE
generic <typename T> generic <typename T>
T GameObject::AddComponent() T GameObject::AddComponent()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::AddComponent<T>(entity); return ECS::AddComponent<T>(entity);
} }
generic <typename T> generic <typename T>
T GameObject::GetComponent() T GameObject::GetComponent()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::GetComponent<T>(entity); return ECS::GetComponent<T>(entity);
} }
generic <typename T> generic <typename T>
T GameObject::GetComponentInChildren() T GameObject::GetComponentInChildren()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::GetComponentInChildren<T>(entity); return ECS::GetComponentInChildren<T>(entity);
} }
generic <typename T> generic <typename T>
T GameObject::EnsureComponent() T GameObject::EnsureComponent()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::EnsureComponent<T>(entity); return ECS::EnsureComponent<T>(entity);
} }
generic <typename T> generic <typename T>
void GameObject::RemoveComponent() void GameObject::RemoveComponent()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
ECS::RemoveComponent<T>(entity); ECS::RemoveComponent<T>(entity);
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Script Access Functions */ /* Script Access Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
generic <typename T> generic <typename T>
T GameObject::AddScript() T GameObject::AddScript()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::AddScript<T>(entity); return ScriptStore::AddScript<T>(entity);
} }
generic <typename T> generic <typename T>
T GameObject::GetScript() T GameObject::GetScript()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::GetScript<T>(entity); return ScriptStore::GetScript<T>(entity);
} }
generic <typename T> generic <typename T>
T GameObject::GetScriptInChildren() T GameObject::GetScriptInChildren()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::GetScriptInChildren<T>(entity); return ScriptStore::GetScriptInChildren<T>(entity);
} }
generic <typename T> generic <typename T>
System::Collections::Generic::IEnumerable<T>^ GameObject::GetScripts() System::Collections::Generic::IEnumerable<T>^ GameObject::GetScripts()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::GetScripts<T>(entity); return ScriptStore::GetScripts<T>(entity);
} }
generic <typename T> generic <typename T>
void GameObject::RemoveScript() void GameObject::RemoveScript()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
ScriptStore::RemoveScript<T>(entity); ScriptStore::RemoveScript<T>(entity);
} }
@ -181,20 +219,24 @@ namespace SHADE
/* Constructors */ /* Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
GameObject::GameObject(const SHEntity& entity) GameObject::GameObject(const SHEntity& entity)
: entity { entity.GetEID() } : entity{ entity.GetEID() }
, children{ gcnew System::Collections::ArrayList } , children{ gcnew System::Collections::ArrayList }
, valid{ true }
{} {}
GameObject::GameObject(Entity entity) GameObject::GameObject(Entity entity)
: entity { entity } : entity{ entity }
, children{ gcnew System::Collections::ArrayList } , children{ gcnew System::Collections::ArrayList }
, valid{ true }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Getters */ /* Getters */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHEntity& GameObject::GetNativeEntity() SHEntity& GameObject::GetNativeEntity()
{ {
if (!valid)
throw gcnew System::NullReferenceException();
SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity); SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity);
if (nativeEntity == nullptr) if (nativeEntity == nullptr)
throw gcnew System::InvalidOperationException("[GameObject] Unable to obtain native Entity for GameObject."); throw gcnew System::InvalidOperationException("[GameObject] Unable to obtain native Entity for GameObject.");
@ -202,14 +244,22 @@ namespace SHADE
return *nativeEntity; return *nativeEntity;
} }
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
GameObject::operator bool(GameObject gameObj)
{
return gameObj.valid;
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* IEquatable */ /* IEquatable */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool GameObject::Equals(GameObject other) bool GameObject::Equals(GameObject other)
{ {
return entity == other.entity; return (!valid && !other.valid) || entity == other.entity;
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Object */ /* Object */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -29,8 +29,9 @@ namespace SHADE
/* Class Definitions */ /* Class Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Lightweight object for an PlushieEngine Entity that allows for easy access /// Lightweight object for an Entity that allows for easy access to Component and
/// to Component and Script operations. /// Script operations.
/// Can be set to a invalid/null GameObject by default construction.
/// </summary> /// </summary>
public value class GameObject : public System::IEquatable<GameObject> public value class GameObject : public System::IEquatable<GameObject>
{ {
@ -98,8 +99,8 @@ namespace SHADE
/// </summary> /// </summary>
property GameObject^ Parent property GameObject^ Parent
{ {
GameObject^ get(); GameObject^ get();
void set(GameObject^); void set(GameObject^);
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -247,12 +248,22 @@ namespace SHADE
/// <returns>Native Entity object that this GameObject represents.</returns> /// <returns>Native Entity object that this GameObject represents.</returns>
SHEntity& GetNativeEntity(); SHEntity& GetNativeEntity();
/*-----------------------------------------------------------------------------*/
/* Operator Overloads */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Implicit conversion operator to enable checking if a GameObject is valid.
/// </summary>
/// <param name="gameObj">GameObjects to check.</param>
static operator bool(GameObject gameObj);
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Entity entity; Entity entity;
System::Collections::ArrayList^ children; System::Collections::ArrayList^ children;
bool valid;
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -171,7 +171,7 @@ namespace SHADE
else if (fieldInfo->FieldType == GameObject::typeid) else if (fieldInfo->FieldType == GameObject::typeid)
{ {
GameObject gameObj = safe_cast<GameObject>(fieldInfo->GetValue(object)); GameObject gameObj = safe_cast<GameObject>(fieldInfo->GetValue(object));
fieldNode = gameObj.GetEntity(); fieldNode = gameObj ? gameObj.GetEntity() : MAX_EID;
} }
else // Not any of the supported types else // Not any of the supported types
{ {
@ -250,7 +250,8 @@ namespace SHADE
} }
else if (fieldInfo->FieldType == GameObject::typeid) else if (fieldInfo->FieldType == GameObject::typeid)
{ {
fieldInfo->SetValue(object, GameObject(node.as<uint32_t>())); const uint32_t EID = node.as<uint32_t>();
fieldInfo->SetValue(object, EID == MAX_EID ? GameObject() : GameObject(EID));
} }
else // Not any of the supported types else // Not any of the supported types
{ {

View File

@ -14,8 +14,13 @@ public class RaccoonSpin : Script
private Transform Transform; private Transform Transform;
public RaccoonSpin(GameObject gameObj) : base(gameObj) { } public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {
testEvent = new CallbackEvent<int>();
Action<int> action = (x) => Debug.Log($"{x}");
testEvent.RegisterAction(action);
Transform = GetComponent<Transform>(); Transform = GetComponent<Transform>();
if (Transform == null) if (Transform == null)
{ {