4 Commits

Author SHA1 Message Date
antopilo
4aa33b6a20 Merge branch 'vulkan-dev' of https://github.com/antopilo/Nuake into vulkan-dev 2025-04-27 23:28:19 -04:00
antopilo
9bd42e1031 Fixed imgui address sanitizer 2025-04-27 23:28:06 -04:00
antopilo
53150dd787 Started proper descriptor management system 2025-04-27 23:26:26 -04:00
antopilo
b77ff499a0 Added ImPlot + GPU Buffer debugger 2025-04-27 23:25:51 -04:00
17 changed files with 14394 additions and 23 deletions

View File

@@ -253,8 +253,6 @@ MaterialEditor::MaterialEditor()
cubeModel->AddMesh(meshBox);
ResourceManager::RegisterResource(cubeModel);
modelComponent.ModelResource = cubeModel->ID;
}
void MaterialEditor::Draw(Ref<Nuake::Material> material)

View File

@@ -66,6 +66,7 @@
#include "../Events/EditorRequests.h"
#include "../../../../Nuake/Thirdparty/glfw/include/GLFW/glfw3.h"
#include "../misc/AnimatedValue.h"
#include <implot-0.16/implot.h>
namespace Nuake {
@@ -2688,11 +2689,13 @@ namespace Nuake {
if (m_ShowGpuResources)
{
if (ImGui::Begin("GPU Resources"))
{
static Ref<AllocatedBuffer> selectedBuffer;
GPUResources& gpu = GPUResources::Get();
auto buffers = gpu.GetAllBuffers();
ImGui::Text("Render Info");
auto stats = VkRenderer::Get().Stats;
@@ -2710,25 +2713,165 @@ namespace Nuake {
const size_t bufferCount = gpu.GetAllBuffers().size();
ImGui::Text(("Buffer Count: " + std::to_string(bufferCount)).c_str());
ImGui::BeginTable("Buffers", 2);
ImGui::TableSetupColumn("UUID", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
ImGui::TableNextColumn();
for (auto& buffer : buffers)
if (selectedBuffer)
{
ImGui::Text(buffer->GetName().c_str());
ImGui::BeginChild("Buffer Info", {ImGui::GetContentRegionAvail().x, 100});
{
{
UIFont boldFont(Bold);
ImGui::Text("Buffer Info");
}
{
ImGui::TableNextColumn();
ImGui::Text(std::to_string(buffer->GetSize()).c_str());
ImGui::TableNextColumn();
ImGui::Text(("Name:" + selectedBuffer->GetName()).c_str());
}
{
ImGui::Text(("Size:" + std::to_string(selectedBuffer->GetSize() / 1024) + " KB").c_str());
}
{
auto type = selectedBuffer->MemUsage;
auto typeString = std::string();
switch (type)
{
case MemoryUsage::CPU_ONLY: typeString = "CPU Only"; break;
case MemoryUsage::GPU_ONLY: typeString = "GPU Only"; break;
case MemoryUsage::CPU_TO_GPU: typeString = "CPU -> GPU"; break;
case MemoryUsage::GPU_TO_CPU: typeString = "GPU -> CPU"; break;
}
ImGui::Text(("Usage: " + typeString).c_str());
}
{
auto currentFrame = VkRenderer::Get().FrameNumber;
auto lastUpdated = selectedBuffer->GetLastUpdated();
auto ago = currentFrame - lastUpdated;
ImGui::Text(("Last Updated: " + std::to_string(ago) + " frames ago").c_str());
}
}
ImGui::EndChild();
}
ImGui::EndTable();
int columnCount = std::sqrt(bufferCount);
std::vector<float> data; // Flattened data to be used in the heatmap
float minVal = FLT_MAX, maxVal = -FLT_MAX; // For normalizing values
ImPlot::PushColormap("Deep"); // You can choose other colormaps, such as ImPlotColormap_Cool
std::vector<Ref<AllocatedBuffer>> bufferInfo;
enum class SortType
{
Size,
Update
};
static SortType sortType = SortType::Size;
static const char* sortTypeLbl[]{ "Size", "Update" };
int selectSort = static_cast<int>(sortType);
ImGui::Combo("##SortType", &selectSort, sortTypeLbl, IM_ARRAYSIZE(sortTypeLbl));
sortType = static_cast<SortType>(selectSort);
auto& sortedBuffers = buffers;
auto sortBySize = [](const Ref<AllocatedBuffer>& a, const Ref<AllocatedBuffer>& b)
{
return a->GetSize() > b->GetSize();
};
auto sortByUpdate = [](const Ref<AllocatedBuffer>& a, const Ref<AllocatedBuffer>& b)
{
return a->GetLastUpdated() > b->GetLastUpdated();
};
using SortFunc = std::function<bool(const Ref<AllocatedBuffer>& a, const Ref<AllocatedBuffer>& b)>;
SortFunc sortFunc = sortBySize;
switch (sortType)
{
case SortType::Size: sortFunc = sortBySize; break;
case SortType::Update: sortFunc = sortByUpdate; break;
default:
sortFunc = sortBySize;
break;
};
std::sort(std::begin(sortedBuffers), std::end(sortedBuffers), sortFunc);
for (auto& buffer : sortedBuffers)
{
float size = buffer->GetSize() / 1024.0f;
data.push_back(size);
bufferInfo.push_back(buffer);
// Update the min/max values for normalization
minVal = std::min(minVal, size);
maxVal = std::max(maxVal, size);
}
// Assuming number of rows is based on the size of the data and column count
int rowCount = data.size() / columnCount;
if (ImPlot::BeginPlot("Buffer view", ImGui::GetContentRegionAvail()))
{
ImPlot::PlotHeatmap("Buffers", data.data(), rowCount, columnCount, minVal, maxVal, "%.2f KB");
auto mousePos = ImPlot::GetPlotMousePos();
// Calculate the hovered square based on mouse position and the grid size
int col = (int)((mousePos.x) * columnCount); // Column in the heatmap
int row = (int)((1.0 - mousePos.y) * rowCount); // Row in the heatmap
ImDrawList* drawList = ImPlot::GetPlotDrawList();
for (int i = 0; i < rowCount * columnCount; i++)
{
int cellRow = i / columnCount;
int cellCol = i % columnCount;
ImPlotPoint pMin((float)cellCol / columnCount, 1.0f - (float)(cellRow + 1) / rowCount);
ImPlotPoint pMax((float)(cellCol + 1) / columnCount, 1.0f - (float)(cellRow) / rowCount);
ImVec2 plotPMin = ImPlot::PlotToPixels(pMin);
ImVec2 plotPMax = ImPlot::PlotToPixels(pMax);
auto& b = bufferInfo[i];
if ((VkRenderer::Get().FrameNumber - b->GetLastUpdated()) <= 1)
{
drawList->AddRect(plotPMin, plotPMax, IM_COL32(255, 0, 0, 128), 0.0f, 0, 4.0f);
}
else if ((VkRenderer::Get().FrameNumber - b->GetLastUpdated()) <= 2)
{
drawList->AddRect(plotPMin, plotPMax, IM_COL32(255, 0, 255, 128), 0.0f, 0, 4.0f);
}
}
// Check if the mouse is over a valid square in the heatmap
if (col >= 0 && col < columnCount && row >= 0 && row < rowCount)
{
// Get the value of the hovered square
size_t index = row * columnCount + col;
float hoveredValue = data[index];
ImPlotPoint pMin((float)col / columnCount, 1.0 - (float)(row + 1) / rowCount);
ImPlotPoint pMax((float)(col + 1) / columnCount, 1.0 - (float)(row) / rowCount);
ImVec2 plotPMin = ImPlot::PlotToPixels(pMin);
ImVec2 plotPMax = ImPlot::PlotToPixels(pMax);
drawList->AddRect(plotPMin, plotPMax, IM_COL32(255, 255, 0, 255), 0.0f, 0, 2.0f); // Yellow outline, thickness 2.0f
// Show the value in a tooltip when hovering over a square
ImGui::SetTooltip(bufferInfo[index]->GetName().c_str());
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
selectedBuffer = bufferInfo[index];
}
}
ImPlot::EndPlot();
}
}
ImGui::End();
}

View File

@@ -0,0 +1,138 @@
#include "BindlessDescriptor.h"
#include "VulkanAllocator.h"
#include "VulkanRenderer.h"
#include "VulkanInit.h"
#include "DescriptorLayoutBuilder.h"
using namespace Nuake;
std::string GetResourceTypeName(ResourceType type)
{
switch (type)
{
case ResourceType::View: return "View";
case ResourceType::Material: return "Material";
case ResourceType::Texture: return "Texture";
case ResourceType::Light: return "Light";
case ResourceType::Sampler: return "Sampler";
default: return "Unknown";
}
}
int32_t Descriptor::LoadResource(const UUID& id)
{
// Check if we have already loaded this resource
if (SlotMapping.find(id) != SlotMapping.end())
{
return SlotMapping[id];
}
// Find an empty slot
for (int i = 0; i < Slots.size(); i++)
{
if (!Slots[i].Active)
{
DescriptorSlot& slot = Slots[i];
slot.Active = true;
slot.Slot = i;
SlotMapping[id] = i;
return i;
}
}
return -1;
}
int32_t Descriptor::GetResourceSlot(const UUID& id) const
{
auto it = SlotMapping.find(id);
if (it != SlotMapping.end())
{
return it->second;
}
return 0; // Resource not found
}
Descriptor::Descriptor(Ref<AllocatedBuffer> buffer, VkDescriptorSetLayout layout, uint8_t* ptr, size_t offset, size_t size, BindlessInfo& info)
: DataPtr(ptr), Offset(offset), Size(size), Info(info)
{
auto& vk = VkRenderer::Get();
auto& allocator = VkRenderer::Get().GetDescriptorAllocator();
DescriptorSet = allocator.Allocate(vk.GetDevice(), layout);
// Offset since we are splitting the buffer by N frames in flight
// Each partition is a frame in flight
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = buffer->GetBuffer();
bufferInfo.offset = offset;
bufferInfo.range = size;
VkWriteDescriptorSet write{};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.dstSet = DescriptorSet;
write.dstBinding = 0;
write.dstArrayElement = 0;
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
write.descriptorCount = 1;
write.pBufferInfo = &bufferInfo;
vkUpdateDescriptorSets(vk.GetDevice(), 1, &write, 0, nullptr);
}
BindlessDescriptor::BindlessDescriptor(ResourceType type, BindlessInfo& info)
{
// 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)
{
case ResourceType::View:
case ResourceType::Material:
case ResourceType::Light:
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
break;
case ResourceType::Texture:
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
break;
}
DescriptorLayout = builder.Build(VkRenderer::Get().GetDevice(), VK_SHADER_STAGE_ALL_GRAPHICS);
VulkanUtil::SetDebugName(DescriptorLayout, resourceName + "DescriptorLayout");
// Create buffer and map, CPU -> GPU since we will writing to it directly
// Size of buffer is: size_of(ResourceType) * FRAME_OVERLAP since 1 buffer will hold N Frames in flight
// TODO(antopilo): move mapped pointer inside buffer directly
const BufferUsage usage = BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST;
const MemoryUsage memoryUsage = MemoryUsage::CPU_TO_GPU;
const size_t size = info.ResourceElementSize[type] * info.ResourceCount[type];
const size_t totalSize = size * FRAME_OVERLAP;
Buffer = CreateRef<AllocatedBuffer>(resourceName + "GPUBuffer", totalSize, usage, memoryUsage);
// Map to a host-visible pointer
void* mappedData;
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (Buffer->GetAllocation()), &mappedData);
for (int i = 0; i < FRAME_OVERLAP; i++)
{
const size_t offset = i * size;
uint8_t* partitionStart = static_cast<uint8_t*>(mappedData) + offset;
Descriptors.emplace_back(Descriptor(Buffer, DescriptorLayout, partitionStart, offset, size));
}
}
ResourceDescriptors::ResourceDescriptors(const ResourceDescriptorsLimits& limits)
{
struct View
{
int myView;
int dat2;
};
AddResourceDescriptors<ResourceType::View, View>(limits.MaxView);
//AddResourceDescriptors<ResourceType::Material>(limits.MaxMaterial);
//AddResourceDescriptors<ResourceType::Texture>(limits.MaxTexture);
//AddResourceDescriptors<ResourceType::Light>(limits.MaxLight);
//AddResourceDescriptors<ResourceType::Sampler>(limits.MaxSampler);
}

View File

@@ -0,0 +1,104 @@
#pragma once
#include "Nuake/Core/Core.h"
#include "VulkanAllocatedBuffer.h"
#include "VulkanRenderer.h"
#include <volk/volk.h>
#include <map>
namespace Nuake
{
enum class ResourceType
{
View,
Material,
Texture,
Light,
Sampler
};
struct BindlessInfo
{
std::map<ResourceType, size_t> ResourceElementSize;
std::map<ResourceType, size_t> ResourceCount;
std::map<ResourceType, AllocatedBuffer> ResourceBuffers;
};
class DescriptorSlot
{
public:
bool Active;
int32_t Slot;
UUID RID;
};
// A partition of the buffer in BindlessDescriptor
class Descriptor
{
private:
uint8_t* DataPtr;
size_t Size;
size_t Offset;
private:
BindlessInfo& Info;
VkDescriptorSet DescriptorSet;
std::map<UUID, int> SlotMapping;
std::vector<DescriptorSlot> Slots;
public:
Descriptor(Ref<AllocatedBuffer> buffer, VkDescriptorSetLayout layout, uint8_t* ptr, size_t offset, size_t size, BindlessInfo& info);
~Descriptor() = default;
int32_t LoadResource(const UUID& id);
int32_t GetResourceSlot(const UUID& id);
};
// Contains buffer for N frames of a resource type
class BindlessDescriptor
{
private:
Ref<AllocatedBuffer> Buffer;
std::vector<Descriptor> Descriptors;
VkDescriptorSetLayout DescriptorLayout;
public:
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);
};
struct ResourceDescriptorsLimits
{
size_t MaxView;
size_t MaxMaterial;
size_t MaxTexture;
size_t MaxLight;
size_t MaxSampler;
};
// Contains all buffers per resource
class ResourceDescriptors
{
private:
std::map<ResourceType, BindlessDescriptor> Descriptors;
BindlessInfo Info;
public:
ResourceDescriptors(const ResourceDescriptorsLimits& limits);
~ResourceDescriptors() = default;
template<ResourceType T, typename S>
void AddResourceDescriptors(const size_t size)
{
Info.ResourceElementSize[T] = sizeof(S);
Info.ResourceCount[T] = size;
Descriptors[T] = BindlessDescriptor(T, (size_t)sizeof(S) * size);
}
};
}

View File

@@ -113,6 +113,8 @@ void Cmd::CopyBuffer(VkBuffer src, VkBuffer dst, size_t size) const
copy.size = size;
vkCmdCopyBuffer(CmdBuffer, src, dst, 1, &copy);
}
void Cmd::TransitionImageLayout(Ref<VulkanImage> img, VkImageLayout layout) const
@@ -177,6 +179,8 @@ void Cmd::CopyImageToBuffer(Ref<VulkanImage> src, Ref<AllocatedBuffer> dst, cons
1,
&copyRegion
);
dst->Update();
}
void Cmd::SetLineRasterizationMode(VkLineRasterizationMode mode) const

View File

@@ -156,6 +156,8 @@ SceneRenderPipeline::SceneRenderPipeline()
copy.size = buffer->GetSize();
vkCmdCopyBuffer(cmd, staging.GetBuffer(), buffer->GetBuffer(), 1, &copy);
buffer->Update();
});
vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), staging.GetAllocation());

View File

@@ -53,7 +53,7 @@ namespace Nuake
// This is the *whole* buffer
struct MaterialData
{
std::array<MaterialBufferStruct, 3000> Data;
std::array<MaterialBufferStruct, 2000> Data;
};
struct LightData
@@ -92,14 +92,22 @@ namespace Nuake
};
constexpr uint32_t MAX_MODEL_MATRIX = 3000;
constexpr uint32_t MAX_MATERIAL = 3000;
constexpr uint32_t MAX_MATERIAL = 2000;
constexpr uint32_t MAX_TEXTURES = 3000;
constexpr uint32_t MAX_CAMERAS = 1000;
constexpr uint32_t MAX_LIGHTS = 100;
class GPUResources
{
Ref<AllocatedBuffer> AllBuffer;
struct FrameData
{
VkDescriptorSet TestDescriptorSet;
};
private:
FrameData frameData[FRAME_OVERLAP];
bool isDirty = false;
std::map<UUID, Ref<AllocatedBuffer>> Buffers;
std::map<UUID, Ref<VkMesh>> Meshes;

View File

@@ -9,6 +9,10 @@
#include "VkResources.h"
using namespace Nuake;
void AllocatedBuffer::Update()
{
LastUpdatedFrame = VkRenderer::Get().FrameNumber;
}
AllocatedBuffer::AllocatedBuffer(size_t inSize, BufferUsage inFlags, MemoryUsage inUsage)
: ID(UUID()),
@@ -25,9 +29,13 @@ AllocatedBuffer::AllocatedBuffer(size_t inSize, BufferUsage inFlags, MemoryUsage
vmaallocInfo.usage = static_cast<VmaMemoryUsage>(inUsage);
vmaallocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
MemUsage = inUsage;
// allocate the buffer
VK_CALL(vmaCreateBuffer(VulkanAllocator::Get().GetAllocator(), &bufferInfo, &vmaallocInfo, &Buffer, &Allocation,
&Info));
LastUpdatedFrame = VkRenderer::Get().FrameNumber;
}
AllocatedBuffer::AllocatedBuffer(const std::string& name, size_t inSize, BufferUsage inFlags, MemoryUsage inUsage) :

View File

@@ -43,6 +43,7 @@ namespace Nuake
VmaAllocation Allocation;
VmaAllocationInfo Info;
size_t Size;
int LastUpdatedFrame = 0;
public:
AllocatedBuffer(size_t size, BufferUsage flags, MemoryUsage usage);
@@ -50,11 +51,17 @@ namespace Nuake
AllocatedBuffer() = default;
~AllocatedBuffer();
MemoryUsage MemUsage;
BufferUsage BufUsage;
VkBuffer GetBuffer() const { return Buffer; }
VmaAllocation GetAllocation() const { return Allocation; }
UUID GetID() const { return ID; }
size_t GetSize() const { return Size; }
int GetLastUpdated() const { return LastUpdatedFrame; }
std::string GetName() const { return Name; }
void Update();
};
// push constants for our mesh object draws

View File

@@ -36,6 +36,7 @@
#include <array>
#include <mutex>
#include <algorithm>
#include <implot-0.16/implot.h>
#ifdef NK_DEBUG
bool NKUseValidationLayer = true;
@@ -606,6 +607,7 @@ void VkRenderer::InitImgui()
// 2: initialize imgui library
ImGui::CreateContext();
ImPlot::CreateContext();
{
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.Fonts->AddFontFromMemoryTTF(StaticResources::Data_Fonts_Poppins_Regular_ttf, StaticResources::Data_Fonts_Poppins_Regular_ttf_len, 16.0);

View File

@@ -4,6 +4,7 @@
#include "GPUManaged.h"
#include "VulkanInit.h"
#include "BindlessDescriptor.h"
using namespace Nuake;
@@ -33,6 +34,54 @@ void GPUResources::Init()
ModelBuffer = CreateBuffer(sizeof(Matrix4) * MAX_MODEL_MATRIX, BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY, "TransformBuffer");
MaterialBuffer = CreateBuffer(sizeof(MaterialBufferStruct) * MAX_MATERIAL, BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY, "MaterialBuffer");
LightBuffer = CreateBuffer(sizeof(LightData) * MAX_LIGHTS, BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY, "LightBuffer");
auto& vk = VkRenderer::Get();
auto device = vk.GetDevice();
{
DescriptorLayoutBuilder builder;
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
ModelDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL_GRAPHICS);
VulkanUtil::SetDebugName(ModelDescriptorLayout, "ModelDescriptorLayout");
}
VkDescriptorSet descriptorSets[FRAME_OVERLAP];
Ref<AllocatedBuffer> 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++)
{
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);
}
//// Update the relevant part
//void* mappedData;
//vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (bigBuffer->GetAllocation()), &mappedData);
//void* mappedPointer = 0;
//int frameIndex = 1;
////uint8_t* frameData = static_cast<uint8_t*>(bigBuffer) + (frameIndex * sizeof(Matrix4) * MAX_MODEL_MATRIX);
//int data = 2;
//// Now copy into the correct frame
//memcpy(frameData, &data, sizeof(Matrix4) * MAX_MODEL_MATRIX);
//vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), bigBuffer->GetAllocation());
}
Ref<AllocatedBuffer> GPUResources::CreateBuffer(size_t size, BufferUsage flags, MemoryUsage usage, const std::string& name)
@@ -56,6 +105,8 @@ void GPUResources::CopyIntoBuffer(Ref<AllocatedBuffer> buffer, void* data, size_
copy.size = size;
vkCmdCopyBuffer(cmd, buffer->GetBuffer(), buffer->GetBuffer(), 1, &copy);
buffer->Update();
});
vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), buffer->GetAllocation());
@@ -288,6 +339,16 @@ void GPUResources::CreateBindlessLayout()
VulkanUtil::SetDebugName(CamerasDescriptorLayout, "CamerasDescriptorLayout");
}
ResourceDescriptorsLimits limits
{
.MaxView = 10,
.MaxMaterial = 1,
.MaxTexture = 20,
.MaxLight = 10,
.MaxSampler = 2,
};
ResourceDescriptors descriptors = ResourceDescriptors(limits);
auto allocator = vk.GetDescriptorAllocator();
TexturesDescriptor = allocator.Allocate(device, TexturesDescriptorLayout);
CamerasDescriptor = allocator.Allocate(device, CamerasDescriptorLayout);
@@ -394,7 +455,7 @@ void GPUResources::RecreateBindlessCameras()
auto allocator = VulkanAllocator::Get().GetAllocator();
vmaMapMemory(allocator, (VkRenderer::Get().GetCurrentFrame().CamerasStagingBuffer->GetAllocation()), &mappedData);
memcpy(mappedData, Cameras.data(), sizeof(CameraView) * Cameras.size());
VkRenderer::Get().GetCurrentFrame().CamerasStagingBuffer->Update();
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd) {
VkBufferCopy copy{ 0 };
copy.dstOffset = 0;
@@ -402,6 +463,7 @@ void GPUResources::RecreateBindlessCameras()
copy.size = sizeof(CameraView) * MAX_CAMERAS;
vkCmdCopyBuffer(cmd, VkRenderer::Get().GetCurrentFrame().CamerasStagingBuffer->GetBuffer(), CamerasBuffer->GetBuffer(), 1, &copy);
CamerasBuffer->Update();
});
vmaUnmapMemory(allocator, VkRenderer::Get().GetCurrentFrame().CamerasStagingBuffer->GetAllocation());
@@ -431,6 +493,7 @@ void GPUResources::UpdateBuffers()
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (VkRenderer::Get().GetCurrentFrame().ModelStagingBuffer->GetAllocation()), &mappedData);
memcpy(mappedData, &ModelTransforms, sizeof(ModelData));
VkRenderer::Get().GetCurrentFrame().ModelStagingBuffer->Update();
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd) {
VkBufferCopy copy{ 0 };
copy.dstOffset = 0;
@@ -438,6 +501,8 @@ void GPUResources::UpdateBuffers()
copy.size = sizeof(ModelData);
vkCmdCopyBuffer(cmd, VkRenderer::Get().GetCurrentFrame().ModelStagingBuffer->GetBuffer(), ModelBuffer->GetBuffer(), 1, &copy);
ModelBuffer->Update();
});
vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), VkRenderer::Get().GetCurrentFrame().ModelStagingBuffer->GetAllocation());
@@ -464,7 +529,7 @@ void GPUResources::UpdateBuffers()
void* mappedData;
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (VkRenderer::Get().GetCurrentFrame().MaterialStagingBuffer->GetAllocation()), &mappedData);
memcpy(mappedData, &MaterialDataContainer, sizeof(MaterialData));
VkRenderer::Get().GetCurrentFrame().MaterialStagingBuffer->Update();
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd) {
VkBufferCopy copy{ 0 };
copy.dstOffset = 0;
@@ -472,6 +537,8 @@ void GPUResources::UpdateBuffers()
copy.size = sizeof(MaterialData);
vkCmdCopyBuffer(cmd, VkRenderer::Get().GetCurrentFrame().MaterialStagingBuffer->GetBuffer(), MaterialBuffer->GetBuffer(), 1, &copy);
MaterialBuffer->Update();
});
vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), VkRenderer::Get().GetCurrentFrame().MaterialStagingBuffer->GetAllocation());
@@ -499,7 +566,7 @@ void GPUResources::UpdateBuffers()
void* mappedData;
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (VkRenderer::Get().GetCurrentFrame().LightStagingBuffer->GetAllocation()), &mappedData);
memcpy(mappedData, &LightDataContainerArray, sizeof(LightDataContainer));
VkRenderer::Get().GetCurrentFrame().LightStagingBuffer->Update();
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd) {
VkBufferCopy copy{ 0 };
copy.dstOffset = 0;
@@ -507,6 +574,7 @@ void GPUResources::UpdateBuffers()
copy.size = sizeof(LightDataContainer);
vkCmdCopyBuffer(cmd, VkRenderer::Get().GetCurrentFrame().LightStagingBuffer->GetBuffer(), LightBuffer->GetBuffer(), 1, &copy);
LightBuffer->Update();
});
vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), VkRenderer::Get().GetCurrentFrame().LightStagingBuffer->GetAllocation());

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Evan Pezent
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff