56 lines
1.8 KiB
C++
56 lines
1.8 KiB
C++
#pragma once
|
|
#include <thread>
|
|
#include <coroutine>
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
#include <vulkan/vulkan.hpp>
|
|
|
|
#include "core/object.h"
|
|
|
|
namespace mirai {
|
|
class texture;
|
|
|
|
struct resource_upload_task {
|
|
std::coroutine_handle<> handle;
|
|
uint64_t target_value = 0;
|
|
std::atomic<bool> is_active{ false };
|
|
};
|
|
|
|
struct resource_async_task {
|
|
struct promise_type {
|
|
resource_async_task get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
|
|
std::suspend_never initial_suspend() { return {}; } // 创建即开始执行
|
|
std::suspend_always final_suspend() noexcept { return {}; }
|
|
void return_void() {}
|
|
void unhandled_exception() { std::terminate(); }
|
|
};
|
|
std::coroutine_handle<promise_type> handle;
|
|
};
|
|
|
|
class resource_manager : public object {
|
|
MIRAI_OBJECT_TYPE_INFO(resource_manager, object)
|
|
public:
|
|
resource_manager(vk::Device device);
|
|
|
|
void add_tracking_task(vk::Semaphore sem, uint64_t value, std::coroutine_handle<> handle);
|
|
resource_async_task upload_resource(const std::shared_ptr<texture>& tex, const std::vector<uint8_t>& data);
|
|
uint64_t dispatch_immediate_transfer(std::shared_ptr<texture> tex, std::shared_ptr<staging_buffer> staging);
|
|
[[nodiscard]] auto get_semaphore() noexcept { return global_timeline_; }
|
|
private:
|
|
void upload_thread_func();
|
|
|
|
vk::Device device_;
|
|
vk::Semaphore global_timeline_;
|
|
std::atomic<uint64_t> last_value_{0};
|
|
|
|
// 池化存储
|
|
std::vector<resource_upload_task> task_pool_;
|
|
std::vector<size_t> active_indices_;
|
|
std::mutex active_mutex_;
|
|
std::mutex submission_mutex_; // 保护 GPU Queue 提交
|
|
std::jthread thread_;
|
|
std::atomic<bool> running_{true};
|
|
};
|
|
}
|