Добавил UniformBuffer. Это умный указатель на память в GPU, но он так же берёт на себя задачу выделения памяти
This commit is contained in:
@@ -10,7 +10,7 @@ void TestActor::print_when_main_camera_rotate(const Vector3D& rot)
|
|||||||
std::string msg = + "(" + name_ + ") camera move to x: " + std::to_string(rot.x) +
|
std::string msg = + "(" + name_ + ") camera move to x: " + std::to_string(rot.x) +
|
||||||
" y: " + std::to_string(rot.y) +
|
" y: " + std::to_string(rot.y) +
|
||||||
" z: " + std::to_string(rot.z);
|
" z: " + std::to_string(rot.z);
|
||||||
Loging::Message(msg);
|
Loging::Log(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestActor::BeginPlay()
|
void TestActor::BeginPlay()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ void TestWorld::print_when_camera_move(const Vector3D& loc_)
|
|||||||
std::string msg = + "(" + name_ + ") camera move to x: " + std::to_string(loc_.x) +
|
std::string msg = + "(" + name_ + ") camera move to x: " + std::to_string(loc_.x) +
|
||||||
" y: " + std::to_string(loc_.y) +
|
" y: " + std::to_string(loc_.y) +
|
||||||
" z: " + std::to_string(loc_.z);
|
" z: " + std::to_string(loc_.z);
|
||||||
Loging::Message(msg);
|
Loging::Log(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestWorld::TestWorld(GameInstance& game_instance) : World(game_instance)
|
TestWorld::TestWorld(GameInstance& game_instance) : World(game_instance)
|
||||||
@@ -26,7 +26,7 @@ void TestWorld::BeginPlay()
|
|||||||
std::vector<std::weak_ptr<Actor>> meshes = GetActorsByClass<Actor>();
|
std::vector<std::weak_ptr<Actor>> meshes = GetActorsByClass<Actor>();
|
||||||
for (const auto& i : meshes)
|
for (const auto& i : meshes)
|
||||||
{
|
{
|
||||||
Loging::Log("Load actor: " + i.lock()->GetName());
|
Loging::Message("Load actor: " + i.lock()->GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
main_camera_ = GetActorsByClass<Camera>()[0];
|
main_camera_ = GetActorsByClass<Camera>()[0];
|
||||||
|
|||||||
@@ -86,9 +86,18 @@ R"(
|
|||||||
std::vector<std::weak_ptr<Actor>> actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass<Actor>();
|
std::vector<std::weak_ptr<Actor>> actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass<Actor>();
|
||||||
ASSERT_EQ(actors.size(), 2);
|
ASSERT_EQ(actors.size(), 2);
|
||||||
|
|
||||||
std::filesystem::remove("Worlds/tests.world");
|
try {
|
||||||
std::filesystem::remove("Worlds");
|
std::filesystem::remove("main_config.conf");
|
||||||
std::filesystem::remove("main_config.conf");
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try {
|
||||||
|
std::filesystem::remove("Worlds/tests.world");
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try {
|
||||||
|
std::filesystem::remove("Worlds");
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(World, check_finders)
|
TEST(World, check_finders)
|
||||||
@@ -187,9 +196,18 @@ R"(
|
|||||||
ASSERT_EQ(actor_by_name.expired(), false);
|
ASSERT_EQ(actor_by_name.expired(), false);
|
||||||
ASSERT_EQ(*actor_by_name.lock()->GetTags().begin(), "Simple");
|
ASSERT_EQ(*actor_by_name.lock()->GetTags().begin(), "Simple");
|
||||||
|
|
||||||
std::filesystem::remove("Worlds/tests.world");
|
try {
|
||||||
std::filesystem::remove("Worlds");
|
std::filesystem::remove("main_config.conf");
|
||||||
std::filesystem::remove("main_config.conf");
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try {
|
||||||
|
std::filesystem::remove("Worlds/tests.world");
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try {
|
||||||
|
std::filesystem::remove("Worlds");
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(World, check_spawn_actor_from_class)
|
TEST(World, check_spawn_actor_from_class)
|
||||||
@@ -232,7 +250,16 @@ R"(
|
|||||||
test_actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass<TestActor>();
|
test_actors = tmp_core.GetGameInstance()->GetWorld()->GetActorsByClass<TestActor>();
|
||||||
ASSERT_EQ(test_actors.size(), 1);
|
ASSERT_EQ(test_actors.size(), 1);
|
||||||
|
|
||||||
std::filesystem::remove("Worlds/tests.world");
|
try {
|
||||||
std::filesystem::remove("Worlds");
|
std::filesystem::remove("main_config.conf");
|
||||||
std::filesystem::remove("main_config.conf");
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try {
|
||||||
|
std::filesystem::remove("Worlds/tests.world");
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
try {
|
||||||
|
std::filesystem::remove("Worlds");
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include "GPU_GarbageCollector.h"
|
||||||
|
#include "DeviceFunctions/DeviceFunctions.hpp"
|
||||||
|
#include "VkObjects/Device.hpp"
|
||||||
|
#include "VkObjects/PhysicalDevice.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class UniformBuffer
|
||||||
|
{
|
||||||
|
const VkObjects::Device& device_;
|
||||||
|
const VkObjects::PhysicalDevice& physical_device_;
|
||||||
|
size_t count_;
|
||||||
|
std::shared_ptr<GPU_GarbageCollector> gc_;
|
||||||
|
|
||||||
|
VkBuffer buffer_ = nullptr;
|
||||||
|
VkDeviceMemory device_memory_ = nullptr;
|
||||||
|
void* map_ = nullptr;
|
||||||
|
public:
|
||||||
|
explicit UniformBuffer( const VkObjects::Device& device,
|
||||||
|
const VkObjects::PhysicalDevice& physical_device,
|
||||||
|
const std::shared_ptr<GPU_GarbageCollector>& gc,
|
||||||
|
size_t count):
|
||||||
|
device_(device), physical_device_(physical_device), count_(count), gc_(gc)
|
||||||
|
{
|
||||||
|
const VkDeviceSize size = sizeof(T) * count;
|
||||||
|
buffer_ = DeviceFunctions::create_buffer(
|
||||||
|
device.get_native(),
|
||||||
|
size,
|
||||||
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
|
physical_device.get_unique_family_indices()
|
||||||
|
);
|
||||||
|
device_memory_ = DeviceFunctions::allocate_device_memory(
|
||||||
|
physical_device.get_native(),
|
||||||
|
device.get_native(),
|
||||||
|
buffer_,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||||
|
);
|
||||||
|
vkBindBufferMemory(device.get_native(), buffer_, device_memory_, 0);
|
||||||
|
|
||||||
|
vkMapMemory(device.get_native(), device_memory_, 0, size, 0, &map_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~UniformBuffer()
|
||||||
|
{
|
||||||
|
if (device_memory_ != nullptr && map_ != nullptr)
|
||||||
|
{
|
||||||
|
vkUnmapMemory(device_.get_native(), device_memory_);
|
||||||
|
map_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
gc_->AddGarbage({buffer_, device_memory_});
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T*() const
|
||||||
|
{
|
||||||
|
return map_;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator void*() const
|
||||||
|
{
|
||||||
|
return map_;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator VkBuffer() const
|
||||||
|
{
|
||||||
|
return buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[](size_t index)
|
||||||
|
{
|
||||||
|
if (index < count_)
|
||||||
|
return map_[index];
|
||||||
|
throw std::runtime_error("Index out of range!");
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -19,18 +19,10 @@ RENDER_ENGINE_FACTORY_GENERATE(UwURenderEngine)
|
|||||||
void UwURenderEngine::create_uniform_buffers()
|
void UwURenderEngine::create_uniform_buffers()
|
||||||
{
|
{
|
||||||
uniform_buffers_.resize(swapchain_.get_images().size());
|
uniform_buffers_.resize(swapchain_.get_images().size());
|
||||||
uniform_buffers_memory_.resize(swapchain_.get_images().size());
|
|
||||||
uniform_buffers_mapped_.resize(swapchain_.get_images().size());
|
|
||||||
|
|
||||||
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
|
||||||
for (size_t i = 0; i < swapchain_.get_images().size(); ++i)
|
|
||||||
{
|
|
||||||
constexpr VkDeviceSize size = sizeof(UniformBufferObject);
|
|
||||||
uniform_buffers_[i] = DeviceFunctions::create_buffer(device_.get_native(), size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, arr_indices);
|
|
||||||
uniform_buffers_memory_[i] = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_.get_native(), uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
|
||||||
vkBindBufferMemory(device_.get_native(), uniform_buffers_[i], uniform_buffers_memory_[i], 0);
|
|
||||||
|
|
||||||
vkMapMemory(device_.get_native(), uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]);
|
for (auto & i : uniform_buffers_)
|
||||||
|
{
|
||||||
|
i.reset(new UniformBuffer<UniformBufferObject>(device_, physical_device_, garbage_collector_, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +56,7 @@ void UwURenderEngine::create_descriptor_sets()
|
|||||||
for (size_t i = 0; i < swapchain_.get_images().size(); ++i)
|
for (size_t i = 0; i < swapchain_.get_images().size(); ++i)
|
||||||
{
|
{
|
||||||
VkDescriptorBufferInfo buffer_info{};
|
VkDescriptorBufferInfo buffer_info{};
|
||||||
buffer_info.buffer = uniform_buffers_[i];
|
buffer_info.buffer = *uniform_buffers_[i];
|
||||||
buffer_info.offset = 0;
|
buffer_info.offset = 0;
|
||||||
buffer_info.range = sizeof(UniformBufferObject);
|
buffer_info.range = sizeof(UniformBufferObject);
|
||||||
|
|
||||||
@@ -282,7 +274,7 @@ void UwURenderEngine::update_uniform_buffer(uint32_t current_frame) const
|
|||||||
ubo.view = glm::lookAt(eye, center, up);
|
ubo.view = glm::lookAt(eye, center, up);
|
||||||
ubo.proj = glm::perspective(glm::radians(45.0f), static_cast<float>(swapchain_.get_extent().width) / static_cast<float>(swapchain_.get_extent().height), 0.1f, 256.0f);
|
ubo.proj = glm::perspective(glm::radians(45.0f), static_cast<float>(swapchain_.get_extent().width) / static_cast<float>(swapchain_.get_extent().height), 0.1f, 256.0f);
|
||||||
ubo.proj[1][1] *= -1;
|
ubo.proj[1][1] *= -1;
|
||||||
memcpy(uniform_buffers_mapped_[current_frame], &ubo, sizeof(ubo));
|
memcpy(*uniform_buffers_[current_frame], &ubo, sizeof(ubo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UwURenderEngine::draw_frame()
|
void UwURenderEngine::draw_frame()
|
||||||
@@ -341,6 +333,9 @@ render_pass_(device_, swapchain_),
|
|||||||
layout_binding_(device_),
|
layout_binding_(device_),
|
||||||
pipeline_(device_, swapchain_, render_pass_, layout_binding_)
|
pipeline_(device_, swapchain_, render_pass_, layout_binding_)
|
||||||
{
|
{
|
||||||
|
garbage_collector_.reset(new GPU_GarbageCollector(device_.get_native()));
|
||||||
|
model_manager_.reset(new ModelManager(physical_device_.get_native(), device_.get_native()));
|
||||||
|
|
||||||
create_uniform_buffers();
|
create_uniform_buffers();
|
||||||
create_descriptor_pool();
|
create_descriptor_pool();
|
||||||
create_descriptor_sets();
|
create_descriptor_sets();
|
||||||
@@ -350,9 +345,6 @@ pipeline_(device_, swapchain_, render_pass_, layout_binding_)
|
|||||||
allocate_command_buffers();
|
allocate_command_buffers();
|
||||||
allocate_index_buffer();
|
allocate_index_buffer();
|
||||||
create_sync_objects();
|
create_sync_objects();
|
||||||
|
|
||||||
garbage_collector_.reset(new GPU_GarbageCollector(device_.get_native()));
|
|
||||||
model_manager_.reset(new ModelManager(physical_device_.get_native(), device_.get_native()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UwURenderEngine::~UwURenderEngine()
|
UwURenderEngine::~UwURenderEngine()
|
||||||
@@ -389,17 +381,11 @@ UwURenderEngine::~UwURenderEngine()
|
|||||||
for (auto& i : framebuffers_)
|
for (auto& i : framebuffers_)
|
||||||
vkDestroyFramebuffer(device_.get_native(), i, nullptr);
|
vkDestroyFramebuffer(device_.get_native(), i, nullptr);
|
||||||
|
|
||||||
for (size_t i = 0; i < uniform_buffers_.size(); ++i)
|
|
||||||
{
|
|
||||||
vkUnmapMemory(device_.get_native(), uniform_buffers_memory_[i]);
|
|
||||||
vkFreeMemory(device_.get_native(), uniform_buffers_memory_[i], nullptr);
|
|
||||||
vkDestroyBuffer(device_.get_native(), uniform_buffers_[i], nullptr);
|
|
||||||
}
|
|
||||||
uniform_buffers_.clear();
|
uniform_buffers_.clear();
|
||||||
uniform_buffers_memory_.clear();
|
|
||||||
uniform_buffers_mapped_.clear();
|
|
||||||
|
|
||||||
vkDestroyDescriptorPool(device_.get_native(), descriptor_pool_, nullptr);
|
vkDestroyDescriptorPool(device_.get_native(), descriptor_pool_, nullptr);
|
||||||
|
|
||||||
|
garbage_collector_->FreeHeap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UwURenderEngine::start()
|
void UwURenderEngine::start()
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#define GLM_FORCE_RADIANS
|
#define GLM_FORCE_RADIANS
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "UniformBuffer.hpp"
|
||||||
#include "VkObjects/DescriptorSetLayout.hpp"
|
#include "VkObjects/DescriptorSetLayout.hpp"
|
||||||
#include "VkObjects/Device.hpp"
|
#include "VkObjects/Device.hpp"
|
||||||
#include "VkObjects/Instance.hpp"
|
#include "VkObjects/Instance.hpp"
|
||||||
@@ -81,9 +82,7 @@ class UwURenderEngine final : public RenderEngineBase
|
|||||||
VkDeviceMemory vertex_buffer_memory_ = VK_NULL_HANDLE;
|
VkDeviceMemory vertex_buffer_memory_ = VK_NULL_HANDLE;
|
||||||
VkBuffer index_buffer_ = VK_NULL_HANDLE;
|
VkBuffer index_buffer_ = VK_NULL_HANDLE;
|
||||||
VkDeviceMemory index_buffer_memory_ = VK_NULL_HANDLE;
|
VkDeviceMemory index_buffer_memory_ = VK_NULL_HANDLE;
|
||||||
std::vector<VkBuffer> uniform_buffers_;
|
std::vector<std::unique_ptr<UniformBuffer<UniformBufferObject>>> uniform_buffers_;
|
||||||
std::vector<VkDeviceMemory> uniform_buffers_memory_;
|
|
||||||
std::vector<void*> uniform_buffers_mapped_;
|
|
||||||
|
|
||||||
// Sync objects
|
// Sync objects
|
||||||
std::vector<VkSemaphore> image_available_semaphores_, render_finished_semaphores_;
|
std::vector<VkSemaphore> image_available_semaphores_, render_finished_semaphores_;
|
||||||
|
|||||||
Reference in New Issue
Block a user