diff --git a/Editor/Source/Editor/ComponentsPanel/CameraPanel.h b/Editor/Source/Editor/ComponentsPanel/CameraPanel.h index 179bba93..49a6e4b1 100644 --- a/Editor/Source/Editor/ComponentsPanel/CameraPanel.h +++ b/Editor/Source/Editor/ComponentsPanel/CameraPanel.h @@ -60,19 +60,19 @@ public: cmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2("Resources/Gizmos/Camera.png"), Engine::GetProject()->Settings.PrimaryColor); }); - previewViewport->GetOnLineDraw().AddStatic([&, componentPtr](DebugCmd& cmd) - { - auto& cam = cmd.GetScene()->m_EditorCamera; - Matrix4 initialTransform = Matrix4(1.0f); - initialTransform = glm::translate(initialTransform, cam->Translation); - - const float aspectRatio = cam->AspectRatio; - const float fov = cam->Fov; - - Matrix4 clampedProj = glm::perspectiveFov(glm::radians(fov), 9.0f * aspectRatio, 9.0f, 0.05f, 3.0f); - Matrix4 boxTransform = glm::translate(scene->GetCurrentCamera()->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix * glm::inverse(clampedProj); - lineCmd.DrawBox(proj * boxTransform, Color(1, 0, 0, 1.0f), 1.5f, false); - }); + previewViewport->GetOnLineDraw().AddStatic([&, componentPtr](DebugLineCmd& cmd) + { + //auto& cam = cmd.GetScene()->m_EditorCamera; + //Matrix4 initialTransform = Matrix4(1.0f); + //initialTransform = glm::translate(initialTransform, cam->Translation); + // + //const float aspectRatio = cam->AspectRatio; + //const float fov = cam->Fov; + // + //Matrix4 clampedProj = glm::perspectiveFov(glm::radians(fov), 9.0f * aspectRatio, 9.0f, 0.05f, 3.0f); + //Matrix4 boxTransform = glm::translate(scene->GetCurrentCamera()->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix * glm::inverse(clampedProj); + //cmd.DrawBox(proj * boxTransform, Color(1, 0, 0, 1.0f), 1.5f, false); + }); vkRenderer.RegisterSceneViewport(scene->Shared(), previewViewport->GetID()); } diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.cpp index fc63ac91..6bcb723c 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.cpp @@ -1,10 +1,13 @@ #include "BindlessDescriptor.h" +#include "Nuake/Core/Logger.h" + #include "VulkanAllocator.h" #include "VulkanRenderer.h" #include "VulkanInit.h" #include "DescriptorLayoutBuilder.h" + using namespace Nuake; std::string GetResourceTypeName(ResourceType type) @@ -80,12 +83,12 @@ Descriptor::Descriptor(Ref buffer, VkDescriptorSetLayout layout vkUpdateDescriptorSets(vk.GetDevice(), 1, &write, 0, nullptr); } - -BindlessDescriptor::BindlessDescriptor(ResourceType type, BindlessInfo& info) +BindlessDescriptor::BindlessDescriptor(ResourceType type, BindlessInfo& info) : + Info(info), + Type(type) { // Create a buffer that holds for N frame in flights of data const std::string& resourceName = GetResourceTypeName(type); - // Build descriptor layout DescriptorLayoutBuilder builder; switch (type) @@ -123,16 +126,42 @@ BindlessDescriptor::BindlessDescriptor(ResourceType type, BindlessInfo& info) } } +void BindlessDescriptor::WriteToBuffer(int32_t frameIndex, void* data, size_t size) +{ + int currentFrame = frameIndex % FRAME_OVERLAP; + auto& desc = Descriptors[currentFrame]; + + const size_t offsetSize = Info.ResourceCount[Type] * Info.ResourceElementSize[Type]; + size_t offset = currentFrame * offsetSize; + + memcpy(desc.DataPtr, data, size); +} + +void BindlessDescriptor::Swap(int32_t frameIndex) +{ + int currentFrame = frameIndex % FRAME_OVERLAP; + int nextFrame = (frameIndex + 1) % FRAME_OVERLAP; + auto& desc = Descriptors[currentFrame]; + auto& nextDesc = Descriptors[nextFrame]; + + // memcpy from currentFrame to next frame + memcpy(desc.DataPtr, nextDesc.DataPtr, desc.Size); +} + ResourceDescriptors::ResourceDescriptors(const ResourceDescriptorsLimits& limits) { - struct View - { - int myView; - int dat2; - }; AddResourceDescriptors(limits.MaxView); //AddResourceDescriptors(limits.MaxMaterial); //AddResourceDescriptors(limits.MaxTexture); //AddResourceDescriptors(limits.MaxLight); //AddResourceDescriptors(limits.MaxSampler); +} + +void ResourceDescriptors::Swap(int32_t frameIndex) +{ + for (auto& [type, desc] : Descriptors) + { + desc.Swap(frameIndex); + Logger::Log("Swapped: " + GetResourceTypeName(type)); + } } \ No newline at end of file diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.h b/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.h index da4044f0..7859f79d 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.h +++ b/Nuake/Source/Nuake/Rendering/Vulkan/BindlessDescriptor.h @@ -37,7 +37,7 @@ namespace Nuake // A partition of the buffer in BindlessDescriptor class Descriptor { - private: + public: uint8_t* DataPtr; size_t Size; size_t Offset; @@ -49,8 +49,11 @@ namespace Nuake std::map SlotMapping; std::vector Slots; + + public: Descriptor(Ref buffer, VkDescriptorSetLayout layout, uint8_t* ptr, size_t offset, size_t size, BindlessInfo& info); + Descriptor() = default; ~Descriptor() = default; int32_t LoadResource(const UUID& id); @@ -64,13 +67,24 @@ namespace Nuake Ref Buffer; std::vector Descriptors; VkDescriptorSetLayout DescriptorLayout; + BindlessInfo Info; + ResourceType Type; public: + // Delete copy + BindlessDescriptor(const BindlessDescriptor&) = delete; + BindlessDescriptor& operator=(const BindlessDescriptor&) = delete; + + // Allow move + BindlessDescriptor(BindlessDescriptor&&) = default; + BindlessDescriptor& operator=(BindlessDescriptor&&) = default; + BindlessDescriptor(ResourceType type, BindlessInfo& info); BindlessDescriptor() = default; ~BindlessDescriptor() = default; - void QueueCopy(const size_t frameIndex, const size_t offset, const size_t size, const void* data); + void WriteToBuffer(int32_t frameIndex, void* data, size_t size); + void Swap(int32_t frameIndex); }; struct ResourceDescriptorsLimits @@ -82,6 +96,12 @@ namespace Nuake size_t MaxSampler; }; + struct View + { + int myView; + int dat2; + }; + // Contains all buffers per resource class ResourceDescriptors { @@ -92,12 +112,21 @@ namespace Nuake ResourceDescriptors(const ResourceDescriptorsLimits& limits); ~ResourceDescriptors() = default; + void Swap(int32_t frameIndex); + + template + void UpdateBuffer(int32_t frameIndex, void* data, size_t size) + { + auto& descriptor = Descriptors[T]; + descriptor.WriteToBuffer(frameIndex, data, size); + } + template void AddResourceDescriptors(const size_t size) { Info.ResourceElementSize[T] = sizeof(S); Info.ResourceCount[T] = size; - //Descriptors[T] = BindlessDescriptor(T, Info); + Descriptors[T] = BindlessDescriptor(T, Info); } }; } \ No newline at end of file diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/VkResources.h b/Nuake/Source/Nuake/Rendering/Vulkan/VkResources.h index a7c46ddb..b114a8a4 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/VkResources.h +++ b/Nuake/Source/Nuake/Rendering/Vulkan/VkResources.h @@ -12,6 +12,8 @@ #include "Nuake/Rendering/Vulkan/VulkanImage/VulkanImage.h" #include "Nuake/Rendering/Vulkan/VulkanRenderer.h" +#include "Nuake/Rendering/Vulkan/BindlessDescriptor.h" + #include #include @@ -106,6 +108,8 @@ namespace Nuake }; private: + Scope resourceDescriptors; + FrameData frameData[FRAME_OVERLAP]; bool isDirty = false; @@ -207,6 +211,8 @@ namespace Nuake void QueueDeletion(CleanUpStack func); void CleanUp(uint32_t frame); + + void Swap(uint32_t frame); private: void CreateBindlessLayout(); CleanUpStack& GetFrameCleanUpStack(uint32_t frame); diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp index b1ef54c8..88e88a66 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanRenderer.cpp @@ -880,6 +880,8 @@ void VkRenderer::EndDraw() // Increase the number of frames drawn FrameNumber++; + + GPUResources::Get().Swap(FrameNumber); } void VkRenderer::DrawImgui(VkCommandBuffer cmd, VkImageView targetImageView) diff --git a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanResources.cpp b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanResources.cpp index 382f6ee0..31682a16 100644 --- a/Nuake/Source/Nuake/Rendering/Vulkan/VulkanResources.cpp +++ b/Nuake/Source/Nuake/Rendering/Vulkan/VulkanResources.cpp @@ -4,7 +4,6 @@ #include "GPUManaged.h" #include "VulkanInit.h" -#include "BindlessDescriptor.h" using namespace Nuake; @@ -45,43 +44,38 @@ void GPUResources::Init() VulkanUtil::SetDebugName(ModelDescriptorLayout, "ModelDescriptorLayout"); } - VkDescriptorSet descriptorSets[FRAME_OVERLAP]; - Ref bigBuffer = CreateBuffer(sizeof(Matrix4) * MAX_MODEL_MATRIX * FRAME_OVERLAP, BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::CPU_TO_GPU, "BigBuffer"); - for (int i = 0; i < FRAME_OVERLAP; i++) + ResourceDescriptorsLimits limits { - auto& allocator = vk.GetDescriptorAllocator(); - descriptorSets[i] = allocator.Allocate(device, ModelDescriptorLayout); - - VkDescriptorBufferInfo bufferInfo{}; - bufferInfo.buffer = bigBuffer->GetBuffer(); - bufferInfo.offset = sizeof(Matrix4) * MAX_MODEL_MATRIX * i; - bufferInfo.range = sizeof(Matrix4) * MAX_MODEL_MATRIX; - - VkWriteDescriptorSet write{}; - write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write.dstSet = descriptorSets[i]; - write.dstBinding = 0; - write.dstArrayElement = 0; - write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - write.descriptorCount = 1; - write.pBufferInfo = &bufferInfo; - - vkUpdateDescriptorSets(device, 1, &write, 0, nullptr); + .MaxView = 1000, + .MaxMaterial = 1000, + .MaxTexture = 1000, + .MaxLight = 1000, + .MaxSampler = 1000, + }; + resourceDescriptors = CreateScope(limits); + + View testData + { + .myView = 1, + .dat2 = 2 + }; + + std::vector testDataVector; + testDataVector.reserve(limits.MaxView); + for (int i = 0; i < limits.MaxView; i++) + { + testDataVector.push_back(testData); } - //// Update the relevant part - //void* mappedData; - //vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (bigBuffer->GetAllocation()), &mappedData); + resourceDescriptors->UpdateBuffer(0, testDataVector.data(), testDataVector.size()); - //void* mappedPointer = 0; - //int frameIndex = 1; - ////uint8_t* frameData = static_cast(bigBuffer) + (frameIndex * sizeof(Matrix4) * MAX_MODEL_MATRIX); + testDataVector[0].myView = 1337; + resourceDescriptors->UpdateBuffer(1, testDataVector.data(), testDataVector.size()); - //int data = 2; - //// Now copy into the correct frame - //memcpy(frameData, &data, sizeof(Matrix4) * MAX_MODEL_MATRIX); - - //vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), bigBuffer->GetAllocation()); + resourceDescriptors->Swap(1); + resourceDescriptors->Swap(0); + resourceDescriptors->UpdateBuffer(1, testDataVector.data(), testDataVector.size()); + resourceDescriptors->Swap(0); } Ref GPUResources::CreateBuffer(size_t size, BufferUsage flags, MemoryUsage usage, const std::string& name) @@ -692,6 +686,11 @@ void GPUResources::CleanUp(uint32_t frame) } } +void GPUResources::Swap(uint32_t frame) +{ + resourceDescriptors->Swap(frame); +} + CleanUpStack& GPUResources::GetFrameCleanUpStack(uint32_t frame) { return DeletionQueue[frame % FRAME_OVERLAP];