mirror of
https://github.com/Kbz-8/42_vox.git
synced 2026-01-11 06:33:36 +00:00
adding async chunk generation
This commit is contained in:
@@ -45,7 +45,7 @@ _GRAY := $(shell $(TPUT) setaf 8)
|
||||
_PURPLE := $(shell $(TPUT) setaf 5)
|
||||
|
||||
ifeq ($(DEBUG), true)
|
||||
CXXFLAGS += -g -D DEBUG -D IMGUI_IMPL_VULKAN_NO_PROTOTYPES -I ThirdParty/imgui
|
||||
CXXFLAGS += -g3 -D DEBUG -D IMGUI_IMPL_VULKAN_NO_PROTOTYPES -I ThirdParty/imgui
|
||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./Runtime/Sources/Debug))
|
||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./ThirdParty/imgui))
|
||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./ThirdParty/imgui/backends))
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Scop
|
||||
std::memcpy(data.GetData() + vertices.size() * sizeof(Vertex), indices.data(), indices.size() * sizeof(std::uint32_t));
|
||||
buffer.Init(vertices.size() * sizeof(Vertex), indices.size() * sizeof(std::uint32_t), 0, std::move(data));
|
||||
this->index_size = index_size == 0 ? indices.size() : index_size;
|
||||
triangle_count = index_size / 3;
|
||||
triangle_count = this->index_size / 3;
|
||||
}
|
||||
|
||||
inline void SetData(const std::vector<Vertex>& vertices, const std::vector<std::uint32_t>& indices, std::size_t index_size = 0)
|
||||
@@ -41,7 +41,7 @@ namespace Scop
|
||||
buffer.SetVertexData(std::move(index_data));
|
||||
|
||||
this->index_size = index_size == 0 ? indices.size() : index_size;
|
||||
triangle_count = index_size / 3;
|
||||
triangle_count = this->index_size / 3;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace Scop
|
||||
~Model() = default;
|
||||
|
||||
private:
|
||||
inline static std::shared_ptr<Material> s_default_material = nullptr;
|
||||
|
||||
Vec3f m_center = { 0.0f, 0.0f, 0.0f };
|
||||
std::vector<std::shared_ptr<Material>> m_materials;
|
||||
std::shared_ptr<Mesh> p_mesh;
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Scop
|
||||
public:
|
||||
GPUBuffer() = default;
|
||||
|
||||
void Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view name = {});
|
||||
void Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view name = {}, bool dedicated_alloc = false);
|
||||
void Destroy() noexcept;
|
||||
|
||||
bool CopyFrom(const GPUBuffer& buffer, std::size_t src_offset = 0, std::size_t dst_offset = 0) noexcept;
|
||||
@@ -43,7 +43,7 @@ namespace Scop
|
||||
MemoryBlock m_memory = NULL_MEMORY_BLOCK;
|
||||
|
||||
private:
|
||||
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, std::string_view name);
|
||||
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, std::string_view name, bool dedicated_alloc);
|
||||
|
||||
private:
|
||||
inline static std::size_t s_buffer_count = 0;
|
||||
@@ -52,6 +52,7 @@ namespace Scop
|
||||
|
||||
VkBufferUsageFlags m_usage = 0;
|
||||
VkMemoryPropertyFlags m_flags = 0;
|
||||
bool m_is_dedicated_alloc = false;
|
||||
};
|
||||
|
||||
class VertexBuffer : public GPUBuffer
|
||||
@@ -77,7 +78,7 @@ namespace Scop
|
||||
{
|
||||
m_vertex_offset = 0;
|
||||
m_index_offset = vertex_size;
|
||||
GPUBuffer::Init(BufferType::LowDynamic, vertex_size + index_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | additional_flags, std::move(data), std::move(name));
|
||||
GPUBuffer::Init(BufferType::LowDynamic, vertex_size + index_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | additional_flags, std::move(data), std::move(name), true);
|
||||
}
|
||||
void SetVertexData(CPUBuffer data);
|
||||
void SetIndexData(CPUBuffer data);
|
||||
|
||||
@@ -12,12 +12,13 @@ namespace Scop
|
||||
class MemoryChunk
|
||||
{
|
||||
public:
|
||||
MemoryChunk(VkDevice device, VkPhysicalDevice physical, VkDeviceSize size, std::int32_t memory_type_index);
|
||||
MemoryChunk(VkDevice device, VkPhysicalDevice physical, VkDeviceSize size, std::int32_t memory_type_index, bool is_dedicated);
|
||||
|
||||
[[nodiscard]] std::optional<MemoryBlock> Allocate(VkDeviceSize size, VkDeviceSize alignment);
|
||||
void Deallocate(const MemoryBlock& block);
|
||||
[[nodiscard]] inline bool Has(const MemoryBlock& block) const noexcept { return block.memory == m_memory; }
|
||||
[[nodiscard]] inline std::int32_t GetMemoryTypeIndex() const noexcept { return m_memory_type_index; }
|
||||
[[nodiscard]] inline bool IsDedicated() const noexcept { return m_is_dedicated; }
|
||||
|
||||
~MemoryChunk();
|
||||
|
||||
@@ -29,6 +30,7 @@ namespace Scop
|
||||
void* p_map = nullptr;
|
||||
VkDeviceSize m_size = 0;
|
||||
std::int32_t m_memory_type_index;
|
||||
bool m_is_dedicated;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef __SCOP_VULKAN_MEMORY_DEVICE_ALLOCATOR__
|
||||
#define __SCOP_VULKAN_MEMORY_DEVICE_ALLOCATOR__
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
@@ -29,6 +30,8 @@ namespace Scop
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice m_physical = VK_NULL_HANDLE;
|
||||
std::size_t m_allocations_count = 0;
|
||||
std::mutex m_alloc_mutex;
|
||||
std::mutex m_dealloc_mutex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define KVF_ENABLE_VALIDATION_LAYERS
|
||||
#endif
|
||||
#include <kvf.h>
|
||||
|
||||
#include <Renderer/Memory/DeviceAllocator.h>
|
||||
@@ -36,17 +33,21 @@ namespace Scop
|
||||
[[nodiscard]] inline VkInstance& GetInstanceRef() noexcept { return m_instance; }
|
||||
[[nodiscard]] inline VkDevice GetDevice() const noexcept { return m_device; }
|
||||
[[nodiscard]] inline VkPhysicalDevice GetPhysicalDevice() const noexcept { return m_physical_device; }
|
||||
[[nodiscard]] inline DeviceAllocator& GetAllocator() noexcept { return m_allocator; }
|
||||
[[nodiscard]] inline DeviceAllocator& GetAllocator() noexcept { return m_allocator; }
|
||||
[[nodiscard]] inline bool StackSubmits() const noexcept { return m_stack_submits; }
|
||||
|
||||
[[nodiscard]] inline std::shared_ptr<class Shader> GetDefaultVertexShader() const { return m_internal_shaders[DEFAULT_VERTEX_SHADER_ID]; }
|
||||
[[nodiscard]] inline std::shared_ptr<class Shader> GetBasicFragmentShader() const { return m_internal_shaders[BASIC_FRAGMENT_SHADER_ID]; }
|
||||
[[nodiscard]] inline std::shared_ptr<class Shader> GetDefaultFragmentShader() const { return m_internal_shaders[DEFAULT_FRAGMENT_SHADER_ID]; }
|
||||
|
||||
inline void WaitDeviceIdle() const noexcept { vkDeviceWaitIdle(m_device); }
|
||||
inline void WaitQueueIdle(KvfQueueType queue) const noexcept { vkQueueWaitIdle(kvfGetDeviceQueue(m_device, queue)); }
|
||||
|
||||
inline static bool IsInit() noexcept { return s_instance != nullptr; }
|
||||
inline static RenderCore& Get() noexcept { return *s_instance; }
|
||||
|
||||
inline void ShouldStackSubmits(bool should) noexcept { m_stack_submits = should; }
|
||||
|
||||
#define SCOP_VULKAN_GLOBAL_FUNCTION(fn) PFN_##fn fn = nullptr;
|
||||
#define SCOP_VULKAN_INSTANCE_FUNCTION(fn) PFN_##fn fn = nullptr;
|
||||
#define SCOP_VULKAN_DEVICE_FUNCTION(fn) PFN_##fn fn = nullptr;
|
||||
@@ -70,6 +71,7 @@ namespace Scop
|
||||
VkInstance m_instance = VK_NULL_HANDLE;
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice m_physical_device = VK_NULL_HANDLE;
|
||||
bool m_stack_submits = false;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace Scop
|
||||
ImGui::Text("Swapchain images count %ld", p_renderer->GetSwapchain().GetSwapchainImages().size());
|
||||
ImGui::Text("Drawcalls %ld", p_renderer->GetDrawCallsCounterRef());
|
||||
ImGui::Text("Polygon drawn %ld", p_renderer->GetPolygonDrawnCounterRef());
|
||||
ImGui::Text("Allocations count %ld", RenderCore::Get().GetAllocator().GetAllocationsCount());
|
||||
ImGui::Text("Allocations count %ld / %u", RenderCore::Get().GetAllocator().GetAllocationsCount(), props.limits.maxMemoryAllocationCount);
|
||||
ImGui::Text("Buffer count %ld", GPUBuffer::GetBufferCount());
|
||||
ImGui::Text("Image count %ld", Image::GetImageCount());
|
||||
ImGui::Text("Window dimensions: %ux%u", p_renderer->GetWindow()->GetWidth(), p_renderer->GetWindow()->GetHeight());
|
||||
|
||||
@@ -12,13 +12,17 @@ namespace Scop
|
||||
if(p_mesh)
|
||||
m_materials.resize(p_mesh->GetSubMeshCount() + 1);
|
||||
|
||||
CPUBuffer default_pixels{ kvfFormatSize(VK_FORMAT_R8G8B8A8_SRGB) };
|
||||
default_pixels.GetDataAs<std::uint32_t>()[0] = 0xFFFFFFFF;
|
||||
std::shared_ptr<Texture> default_texture = std::make_shared<Texture>(std::move(default_pixels), 1, 1, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
if(!s_default_material)
|
||||
{
|
||||
CPUBuffer default_pixels{ kvfFormatSize(VK_FORMAT_R8G8B8A8_SRGB) };
|
||||
default_pixels.GetDataAs<std::uint32_t>()[0] = 0xFFFFFFFF;
|
||||
std::shared_ptr<Texture> default_texture = std::make_shared<Texture>(std::move(default_pixels), 1, 1, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
|
||||
MaterialTextures textures;
|
||||
textures.albedo = default_texture;
|
||||
m_materials.back() = std::make_shared<Material>(textures);
|
||||
MaterialTextures textures;
|
||||
textures.albedo = default_texture;
|
||||
s_default_material = std::make_shared<Material>(textures);
|
||||
}
|
||||
m_materials.back() = s_default_material;
|
||||
}
|
||||
|
||||
void Model::Draw(VkCommandBuffer cmd, const DescriptorSet& matrices_set, const GraphicPipeline& pipeline, DescriptorSet& set, std::size_t& drawcalls, std::size_t& polygondrawn, std::size_t frame_index) const
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
void GPUBuffer::Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view name)
|
||||
void GPUBuffer::Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view name, bool dedicated_alloc)
|
||||
{
|
||||
if(type == BufferType::Constant)
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace Scop
|
||||
if(type == BufferType::Staging && data.Empty())
|
||||
Warning("Vulkan: trying to create staging buffer without data (wtf?)");
|
||||
|
||||
CreateBuffer(size, m_usage, m_flags, std::move(name));
|
||||
CreateBuffer(size, m_usage, m_flags, std::move(name), dedicated_alloc);
|
||||
|
||||
if(!data.Empty())
|
||||
{
|
||||
@@ -41,7 +41,7 @@ namespace Scop
|
||||
PushToGPU();
|
||||
}
|
||||
|
||||
void GPUBuffer::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, std::string_view name)
|
||||
void GPUBuffer::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, std::string_view name, bool dedicated_alloc)
|
||||
{
|
||||
auto device = RenderCore::Get().GetDevice();
|
||||
m_buffer = kvfCreateBuffer(device, usage, size);
|
||||
@@ -49,7 +49,7 @@ namespace Scop
|
||||
VkMemoryRequirements mem_requirements;
|
||||
RenderCore::Get().vkGetBufferMemoryRequirements(device, m_buffer, &mem_requirements);
|
||||
|
||||
m_memory = RenderCore::Get().GetAllocator().Allocate(size, mem_requirements.alignment, *FindMemoryType(mem_requirements.memoryTypeBits, properties));
|
||||
m_memory = RenderCore::Get().GetAllocator().Allocate(size, mem_requirements.alignment, *FindMemoryType(mem_requirements.memoryTypeBits, properties), dedicated_alloc);
|
||||
//m_memory = RenderCore::Get().GetAllocator().Allocate(mem_requirements.size, mem_requirements.alignment, *FindMemoryType(mem_requirements.memoryTypeBits, properties));
|
||||
RenderCore::Get().vkBindBufferMemory(device, m_buffer, m_memory.memory, m_memory.offset);
|
||||
|
||||
@@ -73,12 +73,10 @@ namespace Scop
|
||||
name_info.objectHandle = reinterpret_cast<std::uint64_t>(m_buffer);
|
||||
name_info.pObjectName = m_name.c_str();
|
||||
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
|
||||
|
||||
Message("Vulkan: % buffer created", m_name);
|
||||
#else
|
||||
Message("Vulkan: buffer created");
|
||||
#endif
|
||||
|
||||
m_is_dedicated_alloc = dedicated_alloc;
|
||||
|
||||
s_buffer_count++;
|
||||
}
|
||||
|
||||
@@ -99,10 +97,16 @@ namespace Scop
|
||||
kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
kvfCopyBufferToBuffer(cmd, m_buffer, buffer.Get(), buffer.GetSize(), src_offset, dst_offset);
|
||||
kvfEndCommandBuffer(cmd);
|
||||
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
|
||||
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
|
||||
kvfWaitForFence(RenderCore::Get().GetDevice(), fence);
|
||||
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
|
||||
if(!RenderCore::Get().StackSubmits())
|
||||
{
|
||||
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
|
||||
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
|
||||
kvfWaitForFence(RenderCore::Get().GetDevice(), fence);
|
||||
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
|
||||
kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd);
|
||||
}
|
||||
else
|
||||
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, VK_NULL_HANDLE);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -111,12 +115,11 @@ namespace Scop
|
||||
GPUBuffer new_buffer;
|
||||
new_buffer.m_usage = (this->m_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
new_buffer.m_flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
new_buffer.CreateBuffer(m_memory.size, new_buffer.m_usage, new_buffer.m_flags, m_name);
|
||||
new_buffer.CreateBuffer(m_memory.size, new_buffer.m_usage, new_buffer.m_flags, m_name, m_is_dedicated_alloc);
|
||||
|
||||
if(new_buffer.CopyFrom(*this))
|
||||
Swap(new_buffer);
|
||||
new_buffer.Destroy();
|
||||
Message("Vulkan: pushed buffer to GPU memory");
|
||||
}
|
||||
|
||||
void GPUBuffer::Destroy() noexcept
|
||||
@@ -128,7 +131,6 @@ namespace Scop
|
||||
RenderCore::Get().GetAllocator().Deallocate(m_memory);
|
||||
m_buffer = VK_NULL_HANDLE;
|
||||
m_memory = NULL_MEMORY_BLOCK;
|
||||
Message("Vulkan: destroyed buffer");
|
||||
s_buffer_count--;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,9 +57,6 @@ namespace Scop
|
||||
name_info.objectHandle = reinterpret_cast<std::uint64_t>(m_image);
|
||||
name_info.pObjectName = name.data();
|
||||
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
|
||||
Message("Vulkan: % image created", name);
|
||||
#else
|
||||
Message("Vulkan: image created");
|
||||
#endif
|
||||
|
||||
s_image_count++;
|
||||
@@ -151,7 +148,6 @@ namespace Scop
|
||||
m_memory = NULL_MEMORY_BLOCK;
|
||||
kvfDestroyImage(RenderCore::Get().GetDevice(), m_image);
|
||||
}
|
||||
Message("Vulkan: image destroyed");
|
||||
m_image = VK_NULL_HANDLE;
|
||||
m_memory = NULL_MEMORY_BLOCK;
|
||||
m_image = VK_NULL_HANDLE;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
MemoryChunk::MemoryChunk(VkDevice device, VkPhysicalDevice physical, VkDeviceSize size, std::int32_t memory_type_index)
|
||||
: m_device(device), m_physical(physical), m_size(size), m_memory_type_index(memory_type_index)
|
||||
MemoryChunk::MemoryChunk(VkDevice device, VkPhysicalDevice physical, VkDeviceSize size, std::int32_t memory_type_index, bool is_dedicated)
|
||||
: m_device(device), m_physical(physical), m_size(size), m_memory_type_index(memory_type_index), m_is_dedicated(is_dedicated)
|
||||
{
|
||||
Verify(device != VK_NULL_HANDLE, "Memory Chunk : invalid device");
|
||||
VkMemoryAllocateInfo alloc_info{};
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace Scop
|
||||
{
|
||||
Verify(m_device != VK_NULL_HANDLE, "invalid device");
|
||||
Verify(m_physical != VK_NULL_HANDLE, "invalid physical device");
|
||||
const std::lock_guard<std::mutex> guard(m_alloc_mutex);
|
||||
if(!dedicated_chunk)
|
||||
{
|
||||
for(auto& chunk : m_chunks)
|
||||
@@ -24,7 +25,7 @@ namespace Scop
|
||||
}
|
||||
}
|
||||
}
|
||||
m_chunks.emplace_back(std::make_unique<MemoryChunk>(m_device, m_physical, (CHUNK_SIZE < size + alignment ? size + alignment : CHUNK_SIZE), memory_type_index));
|
||||
m_chunks.emplace_back(std::make_unique<MemoryChunk>(m_device, m_physical, (CHUNK_SIZE < size + alignment ? size + alignment : CHUNK_SIZE), memory_type_index, dedicated_chunk));
|
||||
std::optional<MemoryBlock> block = m_chunks.back()->Allocate(size, alignment);
|
||||
m_allocations_count++;
|
||||
if(block.has_value())
|
||||
@@ -37,11 +38,17 @@ namespace Scop
|
||||
{
|
||||
Verify(m_device != VK_NULL_HANDLE, "invalid device");
|
||||
Verify(m_physical != VK_NULL_HANDLE, "invalid physical device");
|
||||
for(auto& chunk : m_chunks)
|
||||
const std::lock_guard<std::mutex> guard(m_dealloc_mutex);
|
||||
for(auto it = m_chunks.begin(); it != m_chunks.end(); ++it)
|
||||
{
|
||||
if(chunk->Has(block))
|
||||
if((*it)->Has(block))
|
||||
{
|
||||
chunk->Deallocate(block);
|
||||
(*it)->Deallocate(block);
|
||||
if((*it)->IsDedicated())
|
||||
{
|
||||
m_chunks.erase(it);
|
||||
m_allocations_count--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user