diff --git a/Assets/Scenes/M2Scene.shade b/Assets/Scenes/M2Scene.shade index 6086eed9..30dea780 100644 --- a/Assets/Scenes/M2Scene.shade +++ b/Assets/Scenes/M2Scene.shade @@ -226,23 +226,4 @@ Color: {x: 1, y: 1, z: 1, w: 1} Layer: 4294967295 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: ~ \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index de8ac9d2..19d147e6 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -501,9 +501,12 @@ namespace SHADE ImGui_ImplVulkan_DestroyFontUploadObjects(); - renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd) { + renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd) + { + cmd->BeginLabeledSegment("ImGui Draw"); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); - }); + cmd->EndLabeledSegment(); + }); #endif } diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index cc63c565..49cfbfd6 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -288,7 +288,7 @@ namespace SHADE 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()); if (isHovered) @@ -296,7 +296,7 @@ namespace SHADE ImGui::SameLine(); SHEntity* entity = SHEntityManager::GetEntityByID(value); std::ostringstream oss; - if (entity) + if (!alwaysNull && entity) { oss << value << ": " << entity->name; } @@ -314,6 +314,13 @@ namespace SHADE SHDragDrop::EndTarget(); } } + ImGui::SameLine(); + if (ImGui::Button("Clear")) + { + value = MAX_EID; + changed = true; + } + return changed; } diff --git a/SHADE_Engine/src/Editor/SHEditorUI.h b/SHADE_Engine/src/Editor/SHEditorUI.h index d4104639..4e8f4400 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.h +++ b/SHADE_Engine/src/Editor/SHEditorUI.h @@ -313,8 +313,12 @@ namespace SHADE /// Label used to identify this widget. /// Reference to the variable to store the result. /// + /// If set, the field displayed will always be blank regardless of specified + /// GameObject. + /// /// True if the value was changed. - 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); /// /// Creates a combo box for enumeration input. /// diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 08481483..36108628 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -217,9 +217,11 @@ namespace SHADE &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?) &allocCreateInfo, &tempBuffer, &stagingAlloc, &allocInfo); + SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging - " + name); // then assign it to the hpp version stagingBuffer = tempBuffer; + SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, stagingBuffer, "[Buffer] Staging - " + name); // Just map, copy then unmap void* stagingBufferMappedPtr = nullptr; @@ -251,7 +253,11 @@ namespace SHADE auto result = vmaCreateBuffer(vmaAllocator, &bufferCreateInfo.operator VkBufferCreateInfo & (), &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) SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. "); @@ -269,7 +275,7 @@ namespace SHADE */ /***************************************************************************/ - SHVkBuffer::SHVkBuffer(std::reference_wrapper allocator) noexcept + SHVkBuffer::SHVkBuffer(Handle logicalDevice, std::reference_wrapper allocator) noexcept : vkBuffer{} , stagingBuffer{} , sizeStored{ 0 } @@ -277,19 +283,23 @@ namespace SHADE , alloc {nullptr} , randomAccessOptimized{false} , vmaAllocator{allocator} + , device { logicalDevice } {} SHVkBuffer::SHVkBuffer( + Handle logicalDevice, uint32_t inSize, void* data, uint32_t srcSize, std::reference_wrapper allocator, vk::BufferUsageFlags bufferUsage, + const std::string& name, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags ) noexcept - : SHVkBuffer(allocator) + : SHVkBuffer(logicalDevice, allocator) { + this->name = name; Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags); } @@ -304,6 +314,8 @@ namespace SHADE , bufferUsageFlags {rhs.bufferUsageFlags} , bufferCreateInfo { rhs.bufferCreateInfo } , allocCreateInfo { rhs.allocCreateInfo } + , name { std::move(rhs.name) } + , device { rhs.device } { rhs.vkBuffer = VK_NULL_HANDLE; @@ -325,6 +337,8 @@ namespace SHADE bufferCreateInfo = rhs.bufferCreateInfo; allocCreateInfo = rhs.allocCreateInfo; bufferUsageFlags = rhs.bufferUsageFlags; + name = std::move(rhs.name); + device = rhs.device; return *this; } @@ -402,6 +416,8 @@ namespace SHADE auto [tempBuffer, allocInfo] = createBuffer(sizeStored); 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 if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h index eb24d161..1119342c 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h @@ -12,6 +12,7 @@ namespace SHADE //using SHVkBufferUsageBits = vk::BufferUsageFlagBits; class SHVkCommandBuffer; + class SHVkLogicalDevice; class SHVkBuffer { @@ -51,6 +52,11 @@ namespace SHADE //VmaAllocator const& vmaAllocator; std::reference_wrapper vmaAllocator; + //! Name of this buffer if any + std::string name; + //! Handle to the logical device that created this buffer + Handle device; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -62,13 +68,15 @@ namespace SHADE /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ SHVkBuffer (void) noexcept = delete; - SHVkBuffer (std::reference_wrapper allocator) noexcept; + SHVkBuffer (Handle logicalDevice, std::reference_wrapper allocator) noexcept; SHVkBuffer ( + Handle logicalDevice, uint32_t inSize, void* data, uint32_t srcSize, std::reference_wrapper allocator, - vk::BufferUsageFlags bufferUsage, + vk::BufferUsageFlags bufferUsage, + const std::string& name = "", VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO, VmaAllocationCreateFlags allocFlags = {} ) noexcept; @@ -84,7 +92,7 @@ namespace SHADE uint32_t inSize, void* data, uint32_t srcSize, - vk::BufferUsageFlags bufferUsage, + vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags ) noexcept; diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index fb64bcc2..cc35303b 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -105,6 +105,9 @@ namespace SHADE // Set the state to recording if the call above succeeded. cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING; + + // Reset segment count + segmentDepth = 0; } /***************************************************************************/ @@ -507,6 +510,41 @@ namespace SHADE 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(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 //{ // //vkCommandBuffer.pipelineBarrier() diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index bc0d4b04..022d4b62 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -7,6 +7,7 @@ #include "Resource/SHResourceLibrary.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Pipeline/SHPipelineType.h" +#include "Math/SHColour.h" namespace SHADE { @@ -78,7 +79,11 @@ namespace SHADE std::array(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData; //! 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 */ @@ -107,7 +112,7 @@ namespace SHADE void Reset(void); // Begins and Ends - void BeginRecording (void) noexcept; + void BeginRecording () noexcept; void EndRecording (void) noexcept; void BeginRenderpass (Handle const& renderpassHdl, Handle const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept; void EndRenderpass (void) noexcept; @@ -148,6 +153,10 @@ namespace SHADE bool IsReadyToSubmit (void) const noexcept; void HandlePostSubmit (void) noexcept; + // Debugging + void BeginLabeledSegment(const std::string& label) noexcept; + void EndLabeledSegment() noexcept; + // Push Constant variable setting template void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 6bf2e731..808ce750 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -220,6 +220,7 @@ namespace SHADE else { SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. "); + SET_VK_OBJ_NAME(this, vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device"); } InitializeVMA(); @@ -419,9 +420,9 @@ namespace SHADE */ /***************************************************************************/ - Handle SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) const noexcept + Handle 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(inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, memUsage, allocFlags); + return SHVkInstance::GetResourceManager().Create(GetHandle(), inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, name, memUsage, allocFlags); } /***************************************************************************/ @@ -455,12 +456,12 @@ namespace SHADE /***************************************************************************/ Handle 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(&vmaAllocator, w, h, levels, format, usage, create); + return SHVkInstance::GetResourceManager().Create(GetHandle(), &vmaAllocator, w, h, levels, format, usage, create); } Handle SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept { - return SHVkInstance::GetResourceManager().Create(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags); + return SHVkInstance::GetResourceManager().Create(GetHandle(), &vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 2aa59941..158c20b2 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -1,5 +1,4 @@ -#ifndef SH_LOGICAL_DEVICE_H -#define SH_LOGICAL_DEVICE_H +#pragma once #include #include @@ -67,7 +66,6 @@ namespace SHADE class SHVkLogicalDevice : public ISelfHandle { private: - /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ @@ -147,7 +145,8 @@ namespace SHADE uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, - VmaAllocationCreateFlags allocFlags + VmaAllocationCreateFlags allocFlags, + const std::string& name = "" ) const noexcept; Handle CreateImage ( @@ -202,7 +201,33 @@ namespace SHADE Handle CreateSemaphore (void) const noexcept; void UpdateDescriptorSets(std::vector const& writeDescSets) noexcept; - void UpdateDescriptorSet (vk::WriteDescriptorSet const& writeDescSet) noexcept; + void UpdateDescriptorSet(vk::WriteDescriptorSet const& writeDescSet) noexcept; + + /*-----------------------------------------------------------------------*/ + /* Debug Tools */ + /*-----------------------------------------------------------------------*/ +#ifdef _DEBUG + /// + /// 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. + /// + /// Type of the object. + /// Handle to the Vulkan Object to name. + /// Object's name. + template + inline void SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName); + /// + /// 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. + /// + /// Type of the object. + /// Handle to the Vulkan Object to name. + /// Object's name. + template + inline void SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName); +#endif /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ @@ -220,4 +245,4 @@ namespace SHADE }; } -#endif +#include "SHVkLogicalDevice.hpp" diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp new file mode 100644 index 00000000..e8de27fb --- /dev/null +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.hpp @@ -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 + 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(objHandle); + info.pObjectName = objName.data(); + vkLogicalDevice.setDebugUtilsObjectNameEXT(info); + } + template + 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 diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index 00cc31bf..33bed1b5 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp @@ -61,6 +61,7 @@ namespace SHADE &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?) &allocCreateInfo, &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 stagingBuffer = tempBuffer; @@ -107,6 +108,8 @@ namespace SHADE VkImage tempImage; auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); 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) SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); @@ -115,7 +118,8 @@ namespace SHADE } SHVkImage::SHVkImage( - VmaAllocator const* allocator, + Handle logicalDeviceHdl, + VmaAllocator const* allocator, SHImageCreateParams const& imageDetails, const unsigned char* data, uint32_t dataSize, @@ -137,6 +141,7 @@ namespace SHADE , boundToCoherent{false} , randomAccessOptimized {false} , mappedPtr{nullptr} + , device { logicalDeviceHdl } { usageFlags = imageDetails.usageFlags; createFlags = imageDetails.createFlags; @@ -175,7 +180,9 @@ namespace SHADE VmaAllocationInfo allocInfo{}; 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) 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 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} , height{h} , depth {1} @@ -230,11 +237,12 @@ namespace SHADE , usageFlags{usage} , createFlags {create} , vmaAllocator {allocator} + , device { logicalDeviceHdl } { CreateFramebufferImage(); } - Handle SHVkImage::CreateImageView(Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept + Handle SHVkImage::CreateImageView(Handle inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept { return SHVkInstance::GetResourceManager().Create(inLogicalDeviceHdl, parent, createParams); } diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index 4fb16017..ba459def 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -104,6 +104,9 @@ namespace SHADE //! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource std::span mipOffsets; + //! Handle to the device that creates these images + Handle device; + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -117,6 +120,7 @@ namespace SHADE SHVkImage(void) noexcept = default; SHVkImage( + Handle logicalDeviceHdl, VmaAllocator const* allocator, SHImageCreateParams const& imageDetails, const unsigned char* data, @@ -126,7 +130,7 @@ namespace SHADE VmaAllocationCreateFlags allocFlags ) 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 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& operator=(SHVkImage && rhs) noexcept = default; @@ -134,7 +138,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; + Handle CreateImageView (Handle inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; void TransferToDeviceResource (Handle cmdBufferHdl) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 22d1875b..1829096f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -392,20 +392,23 @@ namespace SHADE SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, - BuffUsage::eIndirectBuffer + BuffUsage::eIndirectBuffer, + "Batch Draw Data Buffer" ); // - Transform Buffer const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Batch Transform Buffer" ); const uint32_t EID_DATA_BYTES = static_cast(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES, - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Batch Instance Data Buffer" ); // - Material Properties Buffer rebuildMaterialBuffers(frameIndex, descPool); @@ -427,6 +430,7 @@ namespace SHADE // Bind all required objects before drawing static std::array dynamicOffset{ 0 }; + cmdBuffer->BeginLabeledSegment("SHBatch"); cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); @@ -441,6 +445,7 @@ namespace SHADE ); } cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast(drawData.size())); + cmdBuffer->EndLabeledSegment(); } /*---------------------------------------------------------------------------------*/ @@ -460,7 +465,8 @@ namespace SHADE SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast(matPropsDataSize), - vk::BufferUsageFlagBits::eStorageBuffer + vk::BufferUsageFlagBits::eStorageBuffer, + "Batch Material Data" ); if (!matPropsDescSet[frameIndex]) @@ -470,6 +476,13 @@ namespace SHADE { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, { 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, 1> bufferList = { matPropsBuffer[frameIndex] }; matPropsDescSet[frameIndex]->ModifyWriteDescBuffer diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index 9717889d..53adf2fe 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -13,14 +13,13 @@ namespace SHADE /* Static Definitions */ /*-----------------------------------------------------------------------------------*/ std::vector> SHGraphicsGlobalData::globalDescSetLayouts; - Handle SHGraphicsGlobalData::globalDescSets; SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState; Handle SHGraphicsGlobalData::dummyPipelineLayout; void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept { - } + } /*-----------------------------------------------------------------------------------*/ /* Function Definitions */ @@ -45,7 +44,8 @@ namespace SHADE }; // For global data (generic data and textures) - Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding }); + Handle 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 lightBindings{}; @@ -71,11 +71,11 @@ namespace SHADE }); } - // For Dynamic global data (lights) Handle 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 { .Type = vk::DescriptorType::eUniformBufferDynamic, @@ -83,10 +83,10 @@ namespace SHADE .BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, .DescriptorCount = 1, }; - - // For High frequency global data (camera) Handle 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 { .Type = vk::DescriptorType::eStorageBufferDynamic, @@ -94,9 +94,8 @@ namespace SHADE .BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, .DescriptorCount = 1, }; - - // For High frequency global data (camera) Handle 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(dynamicGlobalLayout); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h index 344c2616..439acba5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h @@ -17,9 +17,6 @@ namespace SHADE //! Global descriptor set layouts. Used to allocate descriptor sets static std::vector> globalDescSetLayouts; - //! Global Descriptor sets - static Handle globalDescSets; - //! Default vertex input state (used by everything). static SHVertexInputState defaultVertexInputState; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp index e36e14e4..883e4894 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp @@ -98,6 +98,7 @@ namespace SHADE // Don't draw if no points if (numPoints[FRAME_IDX] > 0) { + cmdBuffer->BeginLabeledSegment("SHDebugDraw"); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline()); cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); @@ -113,10 +114,12 @@ namespace SHADE // Don't draw if no points if (numPersistentPoints[FRAME_IDX] > 0) { + cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)"); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline()); cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0); cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0); + cmdBuffer->EndLabeledSegment(); } }); @@ -138,7 +141,8 @@ namespace SHADE 0, vk::BufferUsageFlagBits::eVertexBuffer, 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 @@ -151,7 +155,8 @@ namespace SHADE 0, vk::BufferUsageFlagBits::eVertexBuffer, 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" ); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 573c7f7f..15c8ec5d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -1,5 +1,5 @@ /************************************************************************************//*! -\file SHGraphicsSystem.cpp +\file SHGrphicsSystem.cpp \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Aug 21, 2022 @@ -165,7 +165,7 @@ namespace SHADE /* SCENE RENDER GRAPH RESOURCES */ /*-----------------------------------------------------------------------*/ // 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("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); @@ -213,6 +213,7 @@ namespace SHADE ssaoStorage = resourceManager.Create(); 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(); ssaoStorage->Init(device, ssaoTransferCmdBuffer); @@ -234,7 +235,7 @@ namespace SHADE ssaoStorage->PrepareRotationVectorsVkData(device); - Handle ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"}); + Handle ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" }); auto ssaoDataBuffer = ssaoStorage->GetBuffer(); ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored()); 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}); - Handle ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"}); + Handle ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, {"SSAO", "SSAO Blur"}); /*-----------------------------------------------------------------------*/ /* 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 auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors @@ -271,7 +272,11 @@ namespace SHADE // Create debug draw pipeline 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); + 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 @@ -350,7 +355,7 @@ namespace SHADE for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) 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); @@ -677,6 +682,8 @@ namespace SHADE auto renderGraphNode = subpass->GetParentNode(); 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); @@ -723,14 +730,15 @@ namespace SHADE void SHGraphicsSystem::BuildMeshBuffers() { - transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - device->WaitIdle(); + transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, transferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Mesh Buffer Building (Transfer)"); + device->WaitIdle(); transferCmdBuffer->BeginRecording(); meshLibrary.BuildBuffers(device, transferCmdBuffer); transferCmdBuffer->EndRecording(); graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer }); - device->WaitIdle(); - transferCmdBuffer.Free(); transferCmdBuffer = {}; + device->WaitIdle(); + transferCmdBuffer.Free(); transferCmdBuffer = {}; } Handle SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept @@ -750,14 +758,18 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ Handle SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset) { - auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast(texAsset.mipOffsets.size()) }); - return texLibrary.Add(texAsset, sampler); + const int MIPS = texAsset.mipOffsets.size(); + auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast(MIPS) }); + SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS)); + return texLibrary.Add(texAsset, sampler); } SHADE::Handle SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector mipOffsets) { - auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast(mipOffsets.size()) }); - return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler); + const int MIPS = mipOffsets.size(); + auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast(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 tex) @@ -768,6 +780,7 @@ namespace SHADE void SHGraphicsSystem::BuildTextures() { 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(); texLibrary.BuildTextures ( diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp index 3474fea3..d34c1b7d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMeshLibrary.cpp @@ -165,35 +165,40 @@ namespace SHADE device, cmdBuffer, vertPosBuffer, vertPosStorage.data(), static_cast(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex Positions" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, vertTexCoordBuffer, vertTexCoordStorage.data(), static_cast(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex TexCoords" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, vertTangentBuffer, vertTangentStorage.data(), static_cast(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex Tangents" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, vertNormalBuffer, vertNormalStorage.data(), static_cast(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal), - BuffUsage::eVertexBuffer + BuffUsage::eVertexBuffer, + "Mesh Library Vertex Normals" ); SHVkUtil::EnsureBufferAndCopyData ( device, cmdBuffer, indexBuffer, indexStorage.data(), static_cast(indexStorage.size()) * sizeof(SHMesh::Index), - BuffUsage::eIndexBuffer + BuffUsage::eIndexBuffer, + "Mesh Library Indices" ); isDirty = false; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index 46126ae1..86d85c16 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -76,7 +76,7 @@ namespace SHADE uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); // 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 diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index d0deb30c..63d374eb 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -39,9 +39,15 @@ namespace SHADE cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); +#ifdef _DEBUG + const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle(); + for (int i = 0; i < static_cast(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)); - 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}; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 485f859f..02bd8f1f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -134,7 +134,7 @@ namespace SHADE lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights); // 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 { @@ -385,8 +385,12 @@ namespace SHADE std::fill (variableSizes.begin(), variableSizes.end(), 1); // 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(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) { @@ -402,7 +406,7 @@ namespace SHADE lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize); // 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->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp index bbbdd015..96db1ad1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.cpp @@ -26,7 +26,7 @@ namespace SHADE */ /***************************************************************************/ - void SHPerFrameData::Recreate(Handle const& logicalDeviceHdl) noexcept + void SHPerFrameData::Recreate(Handle logicalDeviceHdl) noexcept { // 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); @@ -44,14 +44,17 @@ namespace SHADE // Create image views for the swapchain swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails); + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eImageView, swapchainImageViewHdl->GetImageView(), "[Image View] Swap Chain"); // Create a fence fenceHdl = logicalDeviceHdl->CreateFence(); + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eFence, fenceHdl->GetVkFence(), "[Fence] Swap Chain"); // scope makes it easier to navigate semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semImgAvailableHdl->GetVkSem(), "[Semaphore] Swap Chain Image Available"); semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); - + SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semRenderFinishHdl->GetVkSem(), "[Semaphore] Swap Chain Render Finish"); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h index 5ac38503..d19764c2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHPerFrameData.h @@ -63,7 +63,7 @@ namespace SHADE /* 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 - void Recreate (Handle const& logicalDeviceHdl) noexcept; + void Recreate (Handle logicalDeviceHdl) noexcept; void Destroy (void); friend class SHRenderContext; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp index 45103819..1d24d6f7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp @@ -50,7 +50,13 @@ namespace SHADE 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); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 3b6448fa..b92ccddf 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Images/SHVkImage.h" +#include "Graphics/Images/SHVkImageView.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Assets/Asset Types/SHTextureAsset.h" @@ -78,6 +79,7 @@ namespace SHADE { job.Image = resourceManager.Create ( + device, &device->GetVMAAllocator(), SHImageCreateParams { @@ -142,6 +144,7 @@ namespace SHADE .layerCount = 1 }; 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 @@ -150,6 +153,9 @@ namespace SHADE texOrder.emplace_back(job.TextureHandle); combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal)); job.TextureHandle->TextureArrayIndex = static_cast(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(); @@ -165,6 +171,10 @@ namespace SHADE { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, { static_cast(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 ( SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 93be2413..500bcf04 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -59,7 +59,8 @@ namespace SHADE format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; } - renderGraphStorage->graphResources->try_emplace(resourceName, resourceManager->Create(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + auto resource = resourceManager->Create(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 logicalDevice, Handle swapchain) noexcept + void SHRenderGraph::Init(std::string graphName, Handle logicalDevice, Handle swapchain) noexcept { resourceManager = std::make_shared(); @@ -365,6 +366,8 @@ namespace SHADE renderGraphStorage->resourceManager = resourceManager; renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); + + name = std::move(graphName); } /***************************************************************************/ @@ -390,6 +393,7 @@ namespace SHADE , nodeIndexing{ std::move(rhs.nodeIndexing) } , nodes{ std::move(rhs.nodes) } , resourceManager{ std::move(rhs.resourceManager) } + , name { std::move(rhs.name) } { } @@ -403,6 +407,7 @@ namespace SHADE nodeIndexing = std::move(rhs.nodeIndexing); nodes = std::move(rhs.nodes); resourceManager = std::move(rhs.resourceManager); + name = std::move(rhs.name); return *this; } @@ -467,9 +472,9 @@ namespace SHADE } } - nodes.emplace_back(resourceManager->Create(renderGraphStorage, std::move(descInitParams), std::move(predecessors))); - nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); - return nodes.at(nodeIndexing[nodeName]); + auto node = nodes.emplace_back(resourceManager->Create(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors))); + nodeIndexing.emplace(std::move(nodeName), static_cast(nodes.size()) - 1u); + return node; } /***************************************************************************/ @@ -516,8 +521,10 @@ namespace SHADE // better way to manage these void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept { + cmdBuffer->BeginLabeledSegment(name); for (auto& node : nodes) node->Execute(cmdBuffer, descPool, frameIndex); + cmdBuffer->EndLabeledSegment(); } void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle descPool) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index d90b66df..741cc522 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -69,6 +69,9 @@ namespace SHADE //! Resource library for graph handles std::shared_ptr resourceManager; + //! Name of the RenderGraph + std::string name; + public: /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ @@ -81,7 +84,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle logicalDevice, Handle swapchain) noexcept; + void Init (std::string graphName, Handle logicalDevice, Handle swapchain) noexcept; void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 12f0e246..b3b5b58b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -25,6 +25,7 @@ namespace SHADE void SHRenderGraphNode::CreateRenderpass(void) noexcept { 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); + 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 renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept + SHRenderGraphNode::SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept : graphStorage{ renderGraphStorage} , renderpass{} , framebuffers{} @@ -128,6 +130,7 @@ namespace SHADE , executed{ false } , configured{ false } , nodeComputes{} + , name { std::move(nodeName) } { // pipeline library initialization pipelineLibrary.Init(graphStorage->logicalDevice); @@ -189,6 +192,7 @@ namespace SHADE , spDescs{ std::move(rhs.spDescs) } , spDeps{ std::move(rhs.spDeps) } , nodeComputes{ std::move(rhs.nodeComputes) } + , name { std::move(rhs.name) } { rhs.renderpass = {}; @@ -213,7 +217,7 @@ namespace SHADE spDescs = std::move(rhs.spDescs); spDeps = std::move(rhs.spDeps); nodeComputes = std::move(rhs.nodeComputes); - + name = std::move(rhs.name); rhs.renderpass = {}; @@ -263,7 +267,7 @@ namespace SHADE return subpass; } - Handle SHRenderGraphNode::AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept + Handle SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept { // Look for the required resources in the graph std::vector> nodeComputeResources{}; @@ -276,7 +280,7 @@ namespace SHADE } // Create the subpass compute with the resources - auto nodeCompute = graphStorage->resourceManager->Create(graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty()); + auto nodeCompute = graphStorage->resourceManager->Create(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty()); nodeComputes.push_back(nodeCompute); return nodeCompute; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 695d1c31..4fdac45c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -78,8 +78,11 @@ namespace SHADE //! Whether or not the node has been configured already or not bool configured; + //! Manages batching for this RenderPass SHBatcher batcher; + //! Name of this node + std::string name; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ @@ -92,7 +95,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept; + SHRenderGraphNode(std::string nodeName, Handle renderGraphStorage, std::vector attDescInitParams, std::vector> predecessors) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; @@ -100,7 +103,7 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ Handle AddSubpass(std::string subpassName) noexcept; - Handle AddNodeCompute(Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; + Handle AddNodeCompute(std::string nodeName, Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; void AddDummySubpassIfNeeded (void) noexcept; // TODO: RemoveSubpass() diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index a86acbc7..f4a103f7 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -13,7 +13,7 @@ namespace SHADE { - SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept + SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept : computePipeline{} , pipelineLayout{} , resources{} @@ -22,6 +22,7 @@ namespace SHADE , followingEndRenderpass {followingEndRP} , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} , computeResource{} + , name { std::move(nodeName) } { SHPipelineLayoutParams pipelineLayoutParams { @@ -31,13 +32,15 @@ namespace SHADE }; // Create pipeline layout from parameters - pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams); + pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout(pipelineLayoutParams); // Create the compute pipeline computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout); // and construct it 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 resources = std::move (subpassComputeResources); @@ -50,6 +53,10 @@ namespace SHADE for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) { 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(); auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE]; 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 for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h index 81157dc2..580f018c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h @@ -65,8 +65,11 @@ namespace SHADE std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers; + //! Name of this node + std::string name; + public: - SHRenderGraphNodeCompute(Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept; + SHRenderGraphNodeCompute(std::string nodeName, Handle graphStorage, Handle computeShaderModule, std::vector>&& subpassComputeResources, std::unordered_set&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept; void Execute (Handle cmdBuffer, uint32_t frameIndex) noexcept; void HandleResize (void) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index 502e09b2..4d4099c6 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -82,6 +82,7 @@ namespace SHADE { images[i] = graphStorage->swapchain->GetSwapchainImage(i); 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 @@ -129,7 +130,9 @@ namespace SHADE } // 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 SHImageViewDetails viewDetails @@ -144,7 +147,9 @@ namespace SHADE }; // 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); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 6e78eb9f..2ed84d92 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -201,6 +201,7 @@ namespace SHADE void SHSubpass::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { + commandBuffer->BeginLabeledSegment(name); // Ensure correct transforms are provided superBatch->UpdateBuffers(frameIndex, descPool); @@ -212,7 +213,7 @@ namespace SHADE { drawCall(commandBuffer); } - + commandBuffer->EndLabeledSegment(); } void SHSubpass::HandleResize(void) noexcept @@ -301,6 +302,11 @@ namespace SHADE group.Free(); group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); +#ifdef _DEBUG + const auto& GROUP_HANDLES = group->GetVkHandle(); + for (int i = 0; i < static_cast(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; for (auto& binding : bindings) diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index 8b21e7d1..a9ac543f 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -82,7 +82,7 @@ namespace SHADE } } - void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) + void SHVkUtil::EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name) { if (bufferHandle) { @@ -100,7 +100,8 @@ namespace SHADE size, usage | BuffUsage::eTransferDst, 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); } - void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) + void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name) { if (bufferHandle) { @@ -126,7 +127,8 @@ namespace SHADE size, usage, 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 ); } } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index de700ea5..07e8f02e 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -54,7 +54,7 @@ namespace SHADE */ /***********************************************************************************/ - static void EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); + static void EnsureBufferAndCopyData(Handle device, Handle cmdBuffer, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = ""); /***********************************************************************************/ /*! @@ -80,7 +80,7 @@ namespace SHADE */ /***********************************************************************************/ - static void EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); + static void EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = ""); static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept; }; diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 55fe91da..2afe9697 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -290,9 +290,14 @@ namespace SHADE { GameObject gameObj = safe_cast(field->GetValue(object)); 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); + if (entityId != MAX_EID) + { + // Null GameObject set + newVal = GameObject(entityId); + } field->SetValue(object, newVal); registerUndoAction(object, field, newVal, gameObj); } diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 7ceabfed..9f15c6c9 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -6,9 +6,9 @@ \brief Contains the definition of the functions for the GameObject managed class. Note: This file is written in C++17/CLI. - + 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. *//*************************************************************************************/ // Precompiled Headers @@ -36,10 +36,12 @@ namespace SHADE void GameObject::Destroy(GameObject obj) { + if (!obj.valid) + throw gcnew System::NullReferenceException("Attempted to destroy a null GameObject."); SHEntityManager::DestroyEntity(static_cast(obj.GetEntity())); } - System::Nullable GameObject::Find(System::String ^ name) + System::Nullable GameObject::Find(System::String^ name) { // Search the GameObjectLibrary for an Entity with the specified name const auto ENTITY_ID = SHEntityManager::GetEntityByName(Convert::ToNative(name)); @@ -50,21 +52,27 @@ namespace SHADE return GameObject(ENTITY_ID); } - + /*---------------------------------------------------------------------------------*/ /* Properties */ /*---------------------------------------------------------------------------------*/ System::String^ GameObject::Name::get() { + if (!valid) + throw gcnew System::NullReferenceException(); return Convert::ToCLI(GetNativeEntity().name); - - } + + } bool GameObject::IsActiveSelf::get() { + if (!valid) + throw gcnew System::NullReferenceException(); return GetNativeEntity().GetActive(); } bool GameObject::IsActiveInHierarchy::get() { + if (!valid) + throw gcnew System::NullReferenceException(); auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity()); if (!node) { @@ -75,39 +83,49 @@ namespace SHADE } Entity GameObject::EntityId::get() { + if (!valid) + throw gcnew System::NullReferenceException(); return entity; } GameObject^ GameObject::Parent::get() { - const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); - const auto* ROOT = SCENE_GRAPH.GetRoot(); + if (!valid) + throw gcnew System::NullReferenceException(); + const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); + const auto* ROOT = SCENE_GRAPH.GetRoot(); - const auto* NODE = SCENE_GRAPH.GetNode(entity); - if (NODE == nullptr) - throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString()); + const auto* NODE = SCENE_GRAPH.GetNode(entity); + if (NODE == nullptr) + throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString()); - const auto* PARENT = NODE->GetParent(); - return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr; + const auto* PARENT = NODE->GetParent(); + return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr; } 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) - SCENE_GRAPH.SetParent(entity, nullptr); - else - SCENE_GRAPH.SetParent(entity, newParent->EntityId); + if (newParent == nullptr) + SCENE_GRAPH.SetParent(entity, nullptr); + else + SCENE_GRAPH.SetParent(entity, newParent->EntityId); } - + /*---------------------------------------------------------------------------------*/ /* GameObject Property Functions */ /*---------------------------------------------------------------------------------*/ void GameObject::SetName(System::String^ name) { + if (!valid) + throw gcnew System::NullReferenceException(); GetNativeEntity().name = Convert::ToNative(name); } void GameObject::SetActive(bool active) { + if (!valid) + throw gcnew System::NullReferenceException(); GetNativeEntity().SetActive(active); } @@ -117,63 +135,83 @@ namespace SHADE generic T GameObject::AddComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::AddComponent(entity); } generic T GameObject::GetComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::GetComponent(entity); } generic T GameObject::GetComponentInChildren() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::GetComponentInChildren(entity); } generic T GameObject::EnsureComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); return ECS::EnsureComponent(entity); } generic void GameObject::RemoveComponent() { + if (!valid) + throw gcnew System::NullReferenceException(); ECS::RemoveComponent(entity); } - + /*---------------------------------------------------------------------------------*/ /* Script Access Functions */ /*---------------------------------------------------------------------------------*/ generic T GameObject::AddScript() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::AddScript(entity); } generic T GameObject::GetScript() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::GetScript(entity); } generic T GameObject::GetScriptInChildren() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::GetScriptInChildren(entity); } generic System::Collections::Generic::IEnumerable^ GameObject::GetScripts() { + if (!valid) + throw gcnew System::NullReferenceException(); return ScriptStore::GetScripts(entity); } generic void GameObject::RemoveScript() { + if (!valid) + throw gcnew System::NullReferenceException(); ScriptStore::RemoveScript(entity); } @@ -181,20 +219,24 @@ namespace SHADE /* Constructors */ /*---------------------------------------------------------------------------------*/ GameObject::GameObject(const SHEntity& entity) - : entity { entity.GetEID() } - , children{ gcnew System::Collections::ArrayList } + : entity{ entity.GetEID() } + , children{ gcnew System::Collections::ArrayList } + , valid{ true } {} GameObject::GameObject(Entity entity) - : entity { entity } - , children{ gcnew System::Collections::ArrayList } + : entity{ entity } + , children{ gcnew System::Collections::ArrayList } + , valid{ true } {} - + /*---------------------------------------------------------------------------------*/ /* Getters */ /*---------------------------------------------------------------------------------*/ SHEntity& GameObject::GetNativeEntity() { + if (!valid) + throw gcnew System::NullReferenceException(); SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity); if (nativeEntity == nullptr) throw gcnew System::InvalidOperationException("[GameObject] Unable to obtain native Entity for GameObject."); @@ -202,14 +244,22 @@ namespace SHADE return *nativeEntity; } + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + GameObject::operator bool(GameObject gameObj) + { + return gameObj.valid; + } + /*---------------------------------------------------------------------------------*/ /* IEquatable */ /*---------------------------------------------------------------------------------*/ bool GameObject::Equals(GameObject other) { - return entity == other.entity; + return (!valid && !other.valid) || entity == other.entity; } - + /*---------------------------------------------------------------------------------*/ /* Object */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Engine/GameObject.hxx b/SHADE_Managed/src/Engine/GameObject.hxx index 99296a91..030b917c 100644 --- a/SHADE_Managed/src/Engine/GameObject.hxx +++ b/SHADE_Managed/src/Engine/GameObject.hxx @@ -29,8 +29,9 @@ namespace SHADE /* Class Definitions */ /*---------------------------------------------------------------------------------*/ /// - /// Lightweight object for an PlushieEngine Entity that allows for easy access - /// to Component and Script operations. + /// Lightweight object for an Entity that allows for easy access to Component and + /// Script operations. + /// Can be set to a invalid/null GameObject by default construction. /// public value class GameObject : public System::IEquatable { @@ -98,8 +99,8 @@ namespace SHADE /// property GameObject^ Parent { - GameObject^ get(); - void set(GameObject^); + GameObject^ get(); + void set(GameObject^); } /*-----------------------------------------------------------------------------*/ @@ -247,12 +248,22 @@ namespace SHADE /// Native Entity object that this GameObject represents. SHEntity& GetNativeEntity(); + /*-----------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------*/ + /// + /// Implicit conversion operator to enable checking if a GameObject is valid. + /// + /// GameObjects to check. + static operator bool(GameObject gameObj); + private: /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ Entity entity; System::Collections::ArrayList^ children; + bool valid; public: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx index 4b4e44fc..651afb73 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -171,7 +171,7 @@ namespace SHADE else if (fieldInfo->FieldType == GameObject::typeid) { GameObject gameObj = safe_cast(fieldInfo->GetValue(object)); - fieldNode = gameObj.GetEntity(); + fieldNode = gameObj ? gameObj.GetEntity() : MAX_EID; } else // Not any of the supported types { @@ -250,7 +250,8 @@ namespace SHADE } else if (fieldInfo->FieldType == GameObject::typeid) { - fieldInfo->SetValue(object, GameObject(node.as())); + const uint32_t EID = node.as(); + fieldInfo->SetValue(object, EID == MAX_EID ? GameObject() : GameObject(EID)); } else // Not any of the supported types { diff --git a/TempScriptsFolder/RaccoonSpin.cs b/TempScriptsFolder/RaccoonSpin.cs index c5420ffb..06b3c163 100644 --- a/TempScriptsFolder/RaccoonSpin.cs +++ b/TempScriptsFolder/RaccoonSpin.cs @@ -14,8 +14,13 @@ public class RaccoonSpin : Script private Transform Transform; public RaccoonSpin(GameObject gameObj) : base(gameObj) { } + protected override void awake() { + testEvent = new CallbackEvent(); + Action action = (x) => Debug.Log($"{x}"); + testEvent.RegisterAction(action); + Transform = GetComponent(); if (Transform == null) {