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

@ -227,22 +227,3 @@
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: ~

View File

@ -501,8 +501,11 @@ namespace SHADE
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());
cmd->EndLabeledSegment();
});
#endif
}

View File

@ -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;
}

View File

@ -313,8 +313,12 @@ namespace SHADE
/// <param name="label">Label used to identify this widget.</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="alwaysNull>
/// If set, the field displayed will always be blank regardless of specified
/// GameObject.
/// </param>
/// <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>
/// Creates a combo box for enumeration input.
/// </summary>

View File

@ -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;
@ -252,6 +254,10 @@ namespace SHADE
&bufferCreateInfo.operator VkBufferCreateInfo & (),
&allocCreateInfo,
&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<VmaAllocator const> allocator) noexcept
SHVkBuffer::SHVkBuffer(Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept
: vkBuffer{}
, stagingBuffer{}
, sizeStored{ 0 }
@ -277,19 +283,23 @@ namespace SHADE
, alloc {nullptr}
, randomAccessOptimized{false}
, vmaAllocator{allocator}
, device { logicalDevice }
{}
SHVkBuffer::SHVkBuffer(
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize,
void* data,
uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> 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)

View File

@ -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 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 */
/*-----------------------------------------------------------------------*/
@ -62,13 +68,15 @@ namespace SHADE
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHVkBuffer (void) noexcept = delete;
SHVkBuffer (std::reference_wrapper<VmaAllocator const> allocator) noexcept;
SHVkBuffer (Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept;
SHVkBuffer (
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize,
void* data,
uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> allocator,
vk::BufferUsageFlags bufferUsage,
const std::string& name = "",
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlags allocFlags = {}
) noexcept;

View File

@ -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<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
//{
// //vkCommandBuffer.pipelineBarrier()

View File

@ -7,6 +7,7 @@
#include "Resource/SHResourceLibrary.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/Pipeline/SHPipelineType.h"
#include "Math/SHColour.h"
namespace SHADE
{
@ -80,6 +81,10 @@ namespace SHADE
//! The push constant data for the command buffer
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<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> 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 <typename T>
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept

View File

@ -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<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
{
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
{
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
#define SH_LOGICAL_DEVICE_H
#pragma once
#include <optional>
#include <array>
@ -67,7 +66,6 @@ namespace SHADE
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
{
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<SHVkImage> CreateImage (
@ -204,6 +203,32 @@ namespace SHADE
void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) 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 */
/*-----------------------------------------------------------------------*/
@ -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?)
&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,6 +118,7 @@ namespace SHADE
}
SHVkImage::SHVkImage(
Handle<SHVkLogicalDevice> logicalDeviceHdl,
VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails,
const unsigned char* data,
@ -137,6 +141,7 @@ namespace SHADE
, boundToCoherent{false}
, randomAccessOptimized {false}
, mappedPtr{nullptr}
, device { logicalDeviceHdl }
{
usageFlags = imageDetails.usageFlags;
createFlags = imageDetails.createFlags;
@ -176,6 +181,8 @@ namespace SHADE
VkImage tempImage;
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<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}
, height{h}
, depth {1}
@ -230,11 +237,12 @@ namespace SHADE
, usageFlags{usage}
, createFlags {create}
, vmaAllocator {allocator}
, device { logicalDeviceHdl }
{
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);
}

View File

@ -104,6 +104,9 @@ namespace SHADE
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
std::span<uint32_t> mipOffsets;
//! Handle to the device that creates these images
Handle<SHVkLogicalDevice> device;
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
@ -117,6 +120,7 @@ namespace SHADE
SHVkImage(void) noexcept = default;
SHVkImage(
Handle<SHVkLogicalDevice> 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<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& operator=(SHVkImage && rhs) noexcept = default;
@ -134,7 +138,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* 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 PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;

View File

@ -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<uint32_t>(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<uint32_t>(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<uint32_t, 1> 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<uint32_t>(drawData.size()));
cmdBuffer->EndLabeledSegment();
}
/*---------------------------------------------------------------------------------*/
@ -460,7 +465,8 @@ namespace SHADE
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(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<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer

View File

@ -13,7 +13,6 @@ namespace SHADE
/* Static Definitions */
/*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
Handle<SHVkDescriptorSetGroup> SHGraphicsGlobalData::globalDescSets;
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
@ -46,6 +45,7 @@ namespace SHADE
// For global data (generic data and textures)
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{};
@ -71,11 +71,11 @@ namespace SHADE
});
}
// For Dynamic global data (lights)
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
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
@ -83,10 +83,10 @@ namespace SHADE
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
.DescriptorCount = 1,
};
// For High frequency global data (camera)
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
{
.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<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(dynamicGlobalLayout);

View File

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

View File

@ -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"
);
}
}

View File

@ -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<SHSSAO>();
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<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"});
Handle<SHRenderGraphNodeCompute> 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<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"});
Handle<SHRenderGraphNodeCompute> 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);
@ -724,6 +731,7 @@ namespace SHADE
void SHGraphicsSystem::BuildMeshBuffers()
{
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);
@ -750,13 +758,17 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
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();
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)
{
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) });
const int MIPS = mipOffsets.size();
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);
}
@ -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
(

View File

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

View File

@ -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

View File

@ -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<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));
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};

View File

@ -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
{
@ -386,7 +386,11 @@ namespace SHADE
// Create the descriptor set
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)
{
@ -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);

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.
//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");
}
/***************************************************************************/

View File

@ -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<SHVkLogicalDevice> const& logicalDeviceHdl) noexcept;
void Recreate (Handle<SHVkLogicalDevice> logicalDeviceHdl) noexcept;
void Destroy (void);
friend class SHRenderContext;

View File

@ -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);
}
}

View File

@ -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<SHVkImage>
(
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<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();
@ -165,6 +171,10 @@ namespace SHADE
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
{ 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
(
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,

View File

@ -59,7 +59,8 @@ namespace SHADE
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>();
@ -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<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
return nodes.at(nodeIndexing[nodeName]);
auto node = nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
nodeIndexing.emplace(std::move(nodeName), static_cast<uint32_t>(nodes.size()) - 1u);
return node;
}
/***************************************************************************/
@ -516,8 +521,10 @@ namespace SHADE
// better way to manage these
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
{
cmdBuffer->BeginLabeledSegment(name);
for (auto& node : nodes)
node->Execute(cmdBuffer, descPool, frameIndex);
cmdBuffer->EndLabeledSegment();
}
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)

View File

@ -69,6 +69,9 @@ namespace SHADE
//! Resource library for graph handles
std::shared_ptr<SHResourceHub> resourceManager;
//! Name of the RenderGraph
std::string name;
public:
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
@ -81,7 +84,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* 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 = {});
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
{
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<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}
, 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<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
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
@ -276,7 +280,7 @@ namespace SHADE
}
// 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);
return nodeCompute;

View File

@ -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<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& operator= (SHRenderGraphNode&& rhs) noexcept;
@ -100,7 +103,7 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
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;
// TODO: RemoveSubpass()

View File

@ -13,7 +13,7 @@
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{}
, 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
{
@ -38,6 +39,8 @@ namespace SHADE
// 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<ComputeResource>();
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)

View File

@ -65,8 +65,11 @@ namespace SHADE
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
//! Name of this node
std::string name;
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 HandleResize (void) noexcept;

View File

@ -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);
}
}

View File

@ -201,6 +201,7 @@ namespace SHADE
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> 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<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;
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)
{
@ -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<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)
{
@ -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
);
}
}

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;
};

View File

@ -290,9 +290,14 @@ namespace SHADE
{
GameObject gameObj = safe_cast<GameObject>(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);
}

View File

@ -36,6 +36,8 @@ namespace SHADE
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()));
}
@ -56,15 +58,21 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
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,10 +83,14 @@ namespace SHADE
}
Entity GameObject::EntityId::get()
{
if (!valid)
throw gcnew System::NullReferenceException();
return entity;
}
GameObject^ GameObject::Parent::get()
{
if (!valid)
throw gcnew System::NullReferenceException();
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
const auto* ROOT = SCENE_GRAPH.GetRoot();
@ -91,6 +103,8 @@ namespace SHADE
}
void GameObject::Parent::set(GameObject^ newParent)
{
if (!valid)
throw gcnew System::NullReferenceException();
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
if (newParent == nullptr)
@ -104,10 +118,14 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
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,30 +135,40 @@ namespace SHADE
generic <typename T>
T GameObject::AddComponent()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::AddComponent<T>(entity);
}
generic <typename T>
T GameObject::GetComponent()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::GetComponent<T>(entity);
}
generic <typename T>
T GameObject::GetComponentInChildren()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::GetComponentInChildren<T>(entity);
}
generic <typename T>
T GameObject::EnsureComponent()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ECS::EnsureComponent<T>(entity);
}
generic <typename T>
void GameObject::RemoveComponent()
{
if (!valid)
throw gcnew System::NullReferenceException();
ECS::RemoveComponent<T>(entity);
}
@ -150,30 +178,40 @@ namespace SHADE
generic <typename T>
T GameObject::AddScript()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::AddScript<T>(entity);
}
generic <typename T>
T GameObject::GetScript()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::GetScript<T>(entity);
}
generic <typename T>
T GameObject::GetScriptInChildren()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::GetScriptInChildren<T>(entity);
}
generic <typename T>
System::Collections::Generic::IEnumerable<T>^ GameObject::GetScripts()
{
if (!valid)
throw gcnew System::NullReferenceException();
return ScriptStore::GetScripts<T>(entity);
}
generic <typename T>
void GameObject::RemoveScript()
{
if (!valid)
throw gcnew System::NullReferenceException();
ScriptStore::RemoveScript<T>(entity);
}
@ -183,11 +221,13 @@ namespace SHADE
GameObject::GameObject(const SHEntity& entity)
: entity{ entity.GetEID() }
, children{ gcnew System::Collections::ArrayList }
, valid{ true }
{}
GameObject::GameObject(Entity entity)
: entity{ entity }
, children{ gcnew System::Collections::ArrayList }
, valid{ true }
{}
/*---------------------------------------------------------------------------------*/
@ -195,6 +235,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
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,12 +244,20 @@ 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;
}
/*---------------------------------------------------------------------------------*/

View File

@ -29,8 +29,9 @@ namespace SHADE
/* Class Definitions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// 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.
/// </summary>
public value class GameObject : public System::IEquatable<GameObject>
{
@ -247,12 +248,22 @@ namespace SHADE
/// <returns>Native Entity object that this GameObject represents.</returns>
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:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Entity entity;
System::Collections::ArrayList^ children;
bool valid;
public:
/*-----------------------------------------------------------------------------*/

View File

@ -171,7 +171,7 @@ namespace SHADE
else if (fieldInfo->FieldType == GameObject::typeid)
{
GameObject gameObj = safe_cast<GameObject>(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<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
{

View File

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