v
This commit is contained in:
parent
aa9398bad9
commit
7e90e0f302
@ -11,6 +11,7 @@ time_type last_time = {};
|
|||||||
|
|
||||||
namespace aorii {
|
namespace aorii {
|
||||||
bool init(const window_desc& in_main_window_desc) {
|
bool init(const window_desc& in_main_window_desc) {
|
||||||
|
spdlog::info("初始化 Aorii");
|
||||||
begin_time = std::chrono::high_resolution_clock::now();
|
begin_time = std::chrono::high_resolution_clock::now();
|
||||||
if (!create_font_manager())
|
if (!create_font_manager())
|
||||||
return false;
|
return false;
|
||||||
@ -27,15 +28,18 @@ namespace aorii {
|
|||||||
destroy_window_manager();
|
destroy_window_manager();
|
||||||
destroy_renderer();
|
destroy_renderer();
|
||||||
destroy_font_manager();
|
destroy_font_manager();
|
||||||
|
spdlog::info("Aorii 销毁");
|
||||||
}
|
}
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
thread_pool::global().process_main_thread_callbacks();
|
thread_pool::global().process_main_thread_callbacks();
|
||||||
|
|
||||||
|
// 更新时间
|
||||||
const auto& current_time = std::chrono::high_resolution_clock::now();
|
const auto& current_time = std::chrono::high_resolution_clock::now();
|
||||||
delta_time = current_time - last_time;
|
delta_time = current_time - last_time;
|
||||||
last_time = current_time;
|
last_time = current_time;
|
||||||
|
|
||||||
|
// 更新窗口
|
||||||
get_window_manager()->update();
|
get_window_manager()->update();
|
||||||
|
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
|
192
src/core/renderer/device_selector.cpp
Normal file
192
src/core/renderer/device_selector.cpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
#include "device_selector.h"
|
||||||
|
|
||||||
|
void device_selector::classify_and_sort_devices(const vk::Instance instance, const vk::SurfaceKHR surface) {
|
||||||
|
const auto& physical_devices = instance.enumeratePhysicalDevices();
|
||||||
|
|
||||||
|
// 获取设备的评分列表
|
||||||
|
auto device_scores = get_device_scores(physical_devices, surface);
|
||||||
|
|
||||||
|
// 按评分排序设备(从高到低)
|
||||||
|
auto sort_pred = [](const auto& a, const auto& b) { return a.second > b.second; };
|
||||||
|
std::ranges::sort(device_scores, sort_pred);
|
||||||
|
|
||||||
|
// 根据排序结果将设备分组
|
||||||
|
group_devices(device_scores, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PhysicalDevice device_selector::get_main_device() const {
|
||||||
|
// 优先使用同时支持显示和计算的设备
|
||||||
|
if (!combined_group.empty()) {
|
||||||
|
return combined_group[0];
|
||||||
|
}
|
||||||
|
// 如果没有同时支持显示和计算的设备,则使用显示设备
|
||||||
|
if (!display_group.empty()) {
|
||||||
|
return display_group[0];
|
||||||
|
}
|
||||||
|
// 如果没有显示设备,则使用计算设备
|
||||||
|
if (!compute_group.empty()) {
|
||||||
|
spdlog::warn("没有找到同时支持显示和计算的设备,将使用计算设备");
|
||||||
|
return compute_group[0];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PhysicalDevice device_selector::get_main_compute_device() const {
|
||||||
|
// 优先使用同时支持显示和计算的设备
|
||||||
|
if (!combined_group.empty()) {
|
||||||
|
return combined_group[0];
|
||||||
|
}
|
||||||
|
// 如果没有同时支持显示和计算的设备,则使用计算设备
|
||||||
|
if (!compute_group.empty()) {
|
||||||
|
return compute_group[0];
|
||||||
|
}
|
||||||
|
// 如果没有计算设备,则使用显示设备
|
||||||
|
if (!display_group.empty()) {
|
||||||
|
spdlog::warn("没有找到计算设备,将使用显示设备");
|
||||||
|
return display_group[0];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> device_selector::get_queue_families(vk::PhysicalDevice in_physical_device,
|
||||||
|
const vk::QueueFlags& in_flags) {
|
||||||
|
std::vector<uint32_t> result;
|
||||||
|
const auto queue_families = in_physical_device.getQueueFamilyProperties();
|
||||||
|
for (uint32_t i = 0; i < queue_families.size(); ++i) {
|
||||||
|
if (queue_families[i].queueFlags & in_flags) {
|
||||||
|
result.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<device_selector::device_score> device_selector::get_device_scores(
|
||||||
|
const std::vector<vk::PhysicalDevice>& devices, const vk::SurfaceKHR surface) {
|
||||||
|
std::vector<device_score> deviceScores;
|
||||||
|
|
||||||
|
for (const auto& dev: devices) {
|
||||||
|
int score = score_device(dev, surface);
|
||||||
|
deviceScores.emplace_back(dev, score);
|
||||||
|
}
|
||||||
|
return deviceScores;
|
||||||
|
}
|
||||||
|
|
||||||
|
int device_selector::score_device(const vk::PhysicalDevice& dev, const vk::SurfaceKHR surface) {
|
||||||
|
int score = 0;
|
||||||
|
|
||||||
|
// 获取设备属性和特性
|
||||||
|
const auto& properties = dev.getProperties();
|
||||||
|
const auto& features = dev.getFeatures();
|
||||||
|
|
||||||
|
// 首选独立显卡
|
||||||
|
if (properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) {
|
||||||
|
score += 1000;
|
||||||
|
} else if (properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu) {
|
||||||
|
score += 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询队列族属性
|
||||||
|
const auto& queue_props = dev.getQueueFamilyProperties();
|
||||||
|
bool has_graphics = false;
|
||||||
|
bool has_compute = false;
|
||||||
|
bool can_present = false;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < queue_props.size(); ++i) {
|
||||||
|
const auto& prop = queue_props[i];
|
||||||
|
|
||||||
|
if (prop.queueFlags & vk::QueueFlagBits::eGraphics) {
|
||||||
|
has_graphics = true;
|
||||||
|
score += 100;
|
||||||
|
}
|
||||||
|
if (prop.queueFlags & vk::QueueFlagBits::eCompute) {
|
||||||
|
has_compute = true;
|
||||||
|
score += 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查呈现能力
|
||||||
|
const VkBool32 present_support = dev.getSurfaceSupportKHR(i, surface);
|
||||||
|
if (present_support == VK_TRUE) {
|
||||||
|
can_present = true;
|
||||||
|
score += 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果同时支持图形、计算和呈现,则加额外分
|
||||||
|
if (has_graphics && has_compute && can_present) {
|
||||||
|
score += 500; // 额外奖励
|
||||||
|
}
|
||||||
|
|
||||||
|
// 考虑内存大小
|
||||||
|
const auto& memory_properties = dev.getMemoryProperties();
|
||||||
|
uint64_t total_memory = 0;
|
||||||
|
for (const auto& heap : memory_properties.memoryHeaps) {
|
||||||
|
if (heap.flags & vk::MemoryHeapFlagBits::eDeviceLocal) {
|
||||||
|
total_memory += heap.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
score += static_cast<int>(total_memory / (1024 * 1024 * 1024)); // 每GB加1分
|
||||||
|
|
||||||
|
std::string device_name = properties.deviceName;
|
||||||
|
spdlog::info("{}: {}分", device_name, score);
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
void device_selector::group_devices(const std::vector<device_score>& deviceScores, const vk::SurfaceKHR surface) {
|
||||||
|
for (const auto& [dev, score] : deviceScores) {
|
||||||
|
const device_type& type = classify_device(dev, surface);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case device_type::combined:
|
||||||
|
combined_group.push_back(dev);
|
||||||
|
display_group.push_back(dev);
|
||||||
|
compute_group.push_back(dev);
|
||||||
|
break;
|
||||||
|
case device_type::display:
|
||||||
|
display_group.push_back(dev);
|
||||||
|
break;
|
||||||
|
case device_type::compute:
|
||||||
|
compute_group.push_back(dev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 忽略不符合条件的设备
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
device_selector::device_type device_selector::classify_device(const vk::PhysicalDevice& dev,
|
||||||
|
const vk::SurfaceKHR surface) {
|
||||||
|
bool has_graphics = false;
|
||||||
|
bool has_compute = false;
|
||||||
|
bool can_present = false;
|
||||||
|
|
||||||
|
const auto& queue_props = dev.getQueueFamilyProperties();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < queue_props.size(); ++i) {
|
||||||
|
const auto& prop = queue_props[i];
|
||||||
|
|
||||||
|
if (prop.queueFlags & vk::QueueFlagBits::eGraphics) {
|
||||||
|
has_graphics = true;
|
||||||
|
}
|
||||||
|
if (prop.queueFlags & vk::QueueFlagBits::eCompute) {
|
||||||
|
has_compute = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查呈现能力
|
||||||
|
const VkBool32 present_support = dev.getSurfaceSupportKHR(i, surface);
|
||||||
|
if (present_support == VK_TRUE) {
|
||||||
|
can_present = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_graphics && has_compute && can_present) {
|
||||||
|
return device_type::combined;
|
||||||
|
}
|
||||||
|
if (has_graphics && can_present) {
|
||||||
|
return device_type::display;
|
||||||
|
}
|
||||||
|
if (has_compute) {
|
||||||
|
return device_type::compute;
|
||||||
|
}
|
||||||
|
return device_type::unknown;
|
||||||
|
}
|
@ -8,36 +8,13 @@ class device_selector {
|
|||||||
public:
|
public:
|
||||||
using device_group = std::vector<vk::PhysicalDevice>;
|
using device_group = std::vector<vk::PhysicalDevice>;
|
||||||
|
|
||||||
void classify_and_sort_devices(const vk::Instance instance, const vk::SurfaceKHR surface) {
|
void classify_and_sort_devices(vk::Instance instance, vk::SurfaceKHR surface);
|
||||||
const auto& physical_devices = instance.enumeratePhysicalDevices();
|
|
||||||
|
|
||||||
// 获取设备的评分列表
|
vk::PhysicalDevice get_main_device() const;
|
||||||
auto device_scores = get_device_scores(physical_devices, surface);
|
|
||||||
|
|
||||||
// 按评分排序设备(从高到低)
|
vk::PhysicalDevice get_main_compute_device() const;
|
||||||
auto sort_pred = [](const auto& a, const auto& b) { return a.second > b.second; };
|
|
||||||
std::ranges::sort(device_scores, sort_pred);
|
|
||||||
|
|
||||||
// 根据排序结果将设备分组
|
[[nodiscard]] static std::vector<uint32_t> get_queue_families(vk::PhysicalDevice in_physical_device, const vk::QueueFlags& in_flags);
|
||||||
group_devices(device_scores, surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
vk::PhysicalDevice get_main_device() const {
|
|
||||||
// 优先使用同时支持显示和计算的设备
|
|
||||||
if (!combined_group.empty()) {
|
|
||||||
return combined_group[0];
|
|
||||||
}
|
|
||||||
// 如果没有同时支持显示和计算的设备,则使用显示设备
|
|
||||||
if (!display_group.empty()) {
|
|
||||||
return display_group[0];
|
|
||||||
}
|
|
||||||
// 如果没有显示设备,则使用计算设备
|
|
||||||
if (!compute_group.empty()) {
|
|
||||||
spdlog::warn("没有找到同时支持显示和计算的设备,将使用计算设备");
|
|
||||||
return compute_group[0];
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
device_group combined_group; // 同时支持显示和计算的设备组
|
device_group combined_group; // 同时支持显示和计算的设备组
|
||||||
device_group display_group; // 显示设备组
|
device_group display_group; // 显示设备组
|
||||||
@ -45,134 +22,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
using device_score = std::pair<vk::PhysicalDevice, int>;
|
using device_score = std::pair<vk::PhysicalDevice, int>;
|
||||||
|
|
||||||
static std::vector<device_score> get_device_scores(const std::vector<vk::PhysicalDevice>& devices,
|
static std::vector<device_score> get_device_scores(const std::vector<vk::PhysicalDevice>& devices, vk::SurfaceKHR surface);
|
||||||
const vk::SurfaceKHR surface) {
|
|
||||||
std::vector<device_score> deviceScores;
|
|
||||||
|
|
||||||
for (const auto& dev: devices) {
|
static int score_device(const vk::PhysicalDevice& dev, vk::SurfaceKHR surface);
|
||||||
int score = score_device(dev, surface);
|
|
||||||
deviceScores.emplace_back(dev, score);
|
|
||||||
}
|
|
||||||
return deviceScores;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int score_device(const vk::PhysicalDevice& dev, const vk::SurfaceKHR surface) {
|
void group_devices(const std::vector<device_score>& deviceScores, vk::SurfaceKHR surface);
|
||||||
int score = 0;
|
|
||||||
|
|
||||||
// 获取设备属性和特性
|
static device_type classify_device(const vk::PhysicalDevice& dev, vk::SurfaceKHR surface);
|
||||||
const auto& properties = dev.getProperties();
|
|
||||||
const auto& features = dev.getFeatures();
|
|
||||||
|
|
||||||
// 首选独立显卡
|
|
||||||
if (properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) {
|
|
||||||
score += 1000;
|
|
||||||
} else if (properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu) {
|
|
||||||
score += 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询队列族属性
|
|
||||||
const auto& queue_props = dev.getQueueFamilyProperties();
|
|
||||||
bool has_graphics = false;
|
|
||||||
bool has_compute = false;
|
|
||||||
bool can_present = false;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < queue_props.size(); ++i) {
|
|
||||||
const auto& prop = queue_props[i];
|
|
||||||
|
|
||||||
if (prop.queueFlags & vk::QueueFlagBits::eGraphics) {
|
|
||||||
has_graphics = true;
|
|
||||||
score += 100;
|
|
||||||
}
|
|
||||||
if (prop.queueFlags & vk::QueueFlagBits::eCompute) {
|
|
||||||
has_compute = true;
|
|
||||||
score += 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查呈现能力
|
|
||||||
const VkBool32 present_support = dev.getSurfaceSupportKHR(i, surface);
|
|
||||||
if (present_support == VK_TRUE) {
|
|
||||||
can_present = true;
|
|
||||||
score += 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果同时支持图形、计算和呈现,则加额外分
|
|
||||||
if (has_graphics && has_compute && can_present) {
|
|
||||||
score += 500; // 额外奖励
|
|
||||||
}
|
|
||||||
|
|
||||||
// 考虑内存大小
|
|
||||||
const auto& memory_properties = dev.getMemoryProperties();
|
|
||||||
uint64_t total_memory = 0;
|
|
||||||
for (const auto& heap : memory_properties.memoryHeaps) {
|
|
||||||
if (heap.flags & vk::MemoryHeapFlagBits::eDeviceLocal) {
|
|
||||||
total_memory += heap.size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
score += static_cast<int>(total_memory / (1024 * 1024 * 1024)); // 每GB加1分
|
|
||||||
|
|
||||||
std::string device_name = properties.deviceName;
|
|
||||||
spdlog::info("{}: {}分", device_name, score);
|
|
||||||
return score;
|
|
||||||
}
|
|
||||||
|
|
||||||
void group_devices(const std::vector<device_score>& deviceScores,
|
|
||||||
const vk::SurfaceKHR surface) {
|
|
||||||
for (const auto& [dev, score] : deviceScores) {
|
|
||||||
const device_type& type = classify_device(dev, surface);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case device_type::combined:
|
|
||||||
combined_group.push_back(dev);
|
|
||||||
display_group.push_back(dev);
|
|
||||||
compute_group.push_back(dev);
|
|
||||||
break;
|
|
||||||
case device_type::display:
|
|
||||||
display_group.push_back(dev);
|
|
||||||
break;
|
|
||||||
case device_type::compute:
|
|
||||||
compute_group.push_back(dev);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// 忽略不符合条件的设备
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static device_type classify_device(const vk::PhysicalDevice& dev, const vk::SurfaceKHR surface) {
|
|
||||||
bool has_graphics = false;
|
|
||||||
bool has_compute = false;
|
|
||||||
bool can_present = false;
|
|
||||||
|
|
||||||
const auto& queue_props = dev.getQueueFamilyProperties();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < queue_props.size(); ++i) {
|
|
||||||
const auto& prop = queue_props[i];
|
|
||||||
|
|
||||||
if (prop.queueFlags & vk::QueueFlagBits::eGraphics) {
|
|
||||||
has_graphics = true;
|
|
||||||
}
|
|
||||||
if (prop.queueFlags & vk::QueueFlagBits::eCompute) {
|
|
||||||
has_compute = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查呈现能力
|
|
||||||
const VkBool32 present_support = dev.getSurfaceSupportKHR(i, surface);
|
|
||||||
if (present_support == VK_TRUE) {
|
|
||||||
can_present = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_graphics && has_compute && can_present) {
|
|
||||||
return device_type::combined;
|
|
||||||
}
|
|
||||||
if (has_graphics && can_present) {
|
|
||||||
return device_type::display;
|
|
||||||
}
|
|
||||||
if (has_compute) {
|
|
||||||
return device_type::compute;
|
|
||||||
}
|
|
||||||
return device_type::unknown;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -112,9 +112,11 @@ bool aorii_renderer::init() {
|
|||||||
|
|
||||||
std::vector<const char*> extensions;
|
std::vector<const char*> extensions;
|
||||||
{
|
{
|
||||||
// #if DEBUG
|
#if DEBUG
|
||||||
// extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||||
// #endif
|
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
|
#endif
|
||||||
|
// 交换链
|
||||||
uint32_t glfw_extension_count = 0;
|
uint32_t glfw_extension_count = 0;
|
||||||
auto glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);
|
auto glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);
|
||||||
for (int i = 0; i < glfw_extension_count; ++i) {
|
for (int i = 0; i < glfw_extension_count; ++i) {
|
||||||
@ -126,6 +128,16 @@ bool aorii_renderer::init() {
|
|||||||
|
|
||||||
create_info.setPEnabledExtensionNames(extensions);
|
create_info.setPEnabledExtensionNames(extensions);
|
||||||
}
|
}
|
||||||
|
std::vector<const char*> layers;
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
layers.push_back("VK_LAYER_KHRONOS_validation");
|
||||||
|
create_info.setPEnabledLayerNames(layers);
|
||||||
|
for (auto layer: layers) {
|
||||||
|
spdlog::info("启用层: {}", layer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
instance = createInstance(create_info);
|
instance = createInstance(create_info);
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
@ -140,30 +152,37 @@ bool aorii_renderer::init() {
|
|||||||
|
|
||||||
std::vector<const char*> device_extensions;
|
std::vector<const char*> device_extensions;
|
||||||
device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||||
|
|
||||||
|
std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
|
||||||
|
const auto family_indexes = device_selector::get_queue_families(selector.get_main_device(), vk::QueueFlagBits::eGraphics);
|
||||||
|
for (const auto i : family_indexes) {
|
||||||
|
constexpr float queue_priority = 1.0f;
|
||||||
|
vk::DeviceQueueCreateInfo queue_create_info{};
|
||||||
|
queue_create_info.setQueueFamilyIndex(i);
|
||||||
|
queue_create_info.setQueueCount(1);
|
||||||
|
queue_create_info.setPQueuePriorities(&queue_priority);
|
||||||
|
queue_create_infos.push_back(queue_create_info);
|
||||||
|
}
|
||||||
|
|
||||||
vk::DeviceCreateInfo device_create_info{};
|
vk::DeviceCreateInfo device_create_info{};
|
||||||
device_create_info.setPEnabledExtensionNames(device_extensions);
|
device_create_info.setPEnabledExtensionNames(device_extensions);
|
||||||
main_device.create_device(selector.get_main_device(), device_create_info);
|
device_create_info.setQueueCreateInfos(queue_create_infos);
|
||||||
spdlog::info("Vulkan 主设备: {}", main_device.get_physical_device_name());
|
|
||||||
|
|
||||||
vk::SwapchainCreateInfoKHR swap_chain_create_info{};
|
main_device.create_device(selector.get_main_device(), device_create_info);
|
||||||
swap_chain_create_info.setMinImageCount(2);
|
spdlog::info("Vulkan 主设备使用: {}", main_device.get_physical_device_name());
|
||||||
swap_chain_create_info.setImageFormat(vk::Format::eB8G8R8A8Unorm);
|
for (auto extension: device_extensions) {
|
||||||
swap_chain_create_info.setImageColorSpace(vk::ColorSpaceKHR::eSrgbNonlinear);
|
spdlog::info("启用设备扩展: {}", extension);
|
||||||
swap_chain_create_info.setImageExtent(main_window->get_framebuffer_size());
|
}
|
||||||
swap_chain_create_info.setImageArrayLayers(1);
|
|
||||||
swap_chain_create_info.setImageUsage(vk::ImageUsageFlagBits::eColorAttachment);
|
renderer_swapchain::create_info swapchain_info{};
|
||||||
swap_chain_create_info.setImageSharingMode(vk::SharingMode::eExclusive);
|
if (!main_window->create_swap_chain(swapchain_info))
|
||||||
swap_chain_create_info.setPreTransform(vk::SurfaceTransformFlagBitsKHR::eIdentity);
|
return false;
|
||||||
swap_chain_create_info.setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque);
|
|
||||||
swap_chain_create_info.setPresentMode(vk::PresentModeKHR::eFifo);
|
|
||||||
swap_chain_create_info.setClipped(true);
|
|
||||||
swap_chain_create_info.setOldSwapchain(nullptr);
|
|
||||||
// main_window->create_swap_chain(swap_chain_create_info);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aorii_renderer::destroy() {
|
void aorii_renderer::destroy() {
|
||||||
|
main_device->destroy();
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,6 +195,36 @@ vk::SurfaceKHR aorii_renderer::create_surface(GLFWwindow* in_window) const {
|
|||||||
return { surface };
|
return { surface };
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::SwapchainKHR aorii_renderer::create_swap_chain(const vk::SwapchainCreateInfoKHR& in_create_info) {
|
void aorii_renderer::destroy_surface(const vk::SurfaceKHR& in_surface) const {
|
||||||
return main_device->createSwapchainKHR(in_create_info);
|
instance.destroySurfaceKHR(in_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<device_handle>& aorii_renderer::get_compute_device() const {
|
||||||
|
if (!compute_device.empty()) return compute_device;
|
||||||
|
|
||||||
|
for (const auto& device: selector.compute_group) {
|
||||||
|
const float queue_priority = 1.0f;
|
||||||
|
std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
|
||||||
|
const auto queue_families = device.getQueueFamilyProperties();
|
||||||
|
for (uint32_t i = 0; i < queue_families.size(); ++i) {
|
||||||
|
const bool queue_compute_support = static_cast<bool>(
|
||||||
|
queue_families[i].queueFlags & vk::QueueFlagBits::eCompute);
|
||||||
|
if (queue_compute_support) {
|
||||||
|
vk::DeviceQueueCreateInfo queue_create_info{};
|
||||||
|
queue_create_info.setQueueFamilyIndex(i);
|
||||||
|
queue_create_info.setQueueCount(1);
|
||||||
|
queue_create_info.setPQueuePriorities(&queue_priority);
|
||||||
|
queue_create_infos.push_back(queue_create_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
device_handle handle;
|
||||||
|
vk::DeviceCreateInfo device_create_info{};
|
||||||
|
device_create_info.setQueueCreateInfos(queue_create_infos);
|
||||||
|
handle.create_device(device, device_create_info);
|
||||||
|
spdlog::info("创建 Vulkan 计算设备: {}", handle.get_physical_device_name());
|
||||||
|
compute_device.push_back(handle);
|
||||||
|
}
|
||||||
|
return compute_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "device_selector.h"
|
#include "device_selector.h"
|
||||||
|
#include "renderer_swapchain.h"
|
||||||
#include "renderer_types.h"
|
#include "renderer_types.h"
|
||||||
|
|
||||||
struct window_desc;
|
struct window_desc;
|
||||||
@ -15,11 +16,14 @@ public:
|
|||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
vk::SurfaceKHR create_surface(GLFWwindow* in_window) const;
|
vk::SurfaceKHR create_surface(GLFWwindow* in_window) const;
|
||||||
vk::SwapchainKHR create_swap_chain(const vk::SwapchainCreateInfoKHR& in_create_info);
|
void destroy_surface(const vk::SurfaceKHR& in_surface) const;
|
||||||
|
device_handle get_main_device() const { return main_device; }
|
||||||
|
const std::vector<device_handle>& get_compute_device() const;
|
||||||
private:
|
private:
|
||||||
vk::Instance instance;
|
vk::Instance instance;
|
||||||
device_selector selector;
|
device_selector selector;
|
||||||
device_set main_device;
|
device_handle main_device;
|
||||||
|
mutable std::vector<device_handle> compute_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace aorii {
|
namespace aorii {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#include "renderer_buffer_memory_strategy.h"
|
#include "renderer_buffer_memory_strategy.h"
|
||||||
|
|
||||||
uint32_t device_set::get_physical_device_id() const {
|
uint32_t device_handle::get_physical_device_id() const {
|
||||||
const auto& props = physical_device.getProperties();
|
const auto& props = physical_device.getProperties();
|
||||||
return props.deviceID;
|
return props.deviceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string device_set::get_physical_device_name() const {
|
std::string device_handle::get_physical_device_name() const {
|
||||||
const auto& props = physical_device.getProperties();
|
const auto& props = physical_device.getProperties();
|
||||||
return props.deviceName;
|
return props.deviceName;
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ renderer_buffer_desc::operator vk::BufferCreateInfo() const {
|
|||||||
return buffer_info;
|
return buffer_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_buffer::renderer_buffer(const device_set& in_device, const renderer_buffer_desc& in_desc) {
|
renderer_buffer::renderer_buffer(const device_handle& in_device, const renderer_buffer_desc& in_desc) {
|
||||||
device = in_device;
|
device = in_device;
|
||||||
desc = in_desc;
|
desc = in_desc;
|
||||||
memory_strategy = buffer_memory_strategy::create(in_desc.memory_props);
|
memory_strategy = buffer_memory_strategy::create(in_desc.memory_props);
|
||||||
|
@ -8,7 +8,7 @@ class buffer_memory_strategy;
|
|||||||
|
|
||||||
class renderer_buffer {
|
class renderer_buffer {
|
||||||
public:
|
public:
|
||||||
explicit renderer_buffer(const device_set& in_device, const renderer_buffer_desc& in_desc);
|
explicit renderer_buffer(const device_handle& in_device, const renderer_buffer_desc& in_desc);
|
||||||
|
|
||||||
virtual ~renderer_buffer();
|
virtual ~renderer_buffer();
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void resize(vk::DeviceSize in_new_size, vk::CommandBuffer in_command_buffer, bool in_preserve_data = true, bool in_allow_in_place = true, float in_growth_factor = 1.5f);
|
void resize(vk::DeviceSize in_new_size, vk::CommandBuffer in_command_buffer, bool in_preserve_data = true, bool in_allow_in_place = true, float in_growth_factor = 1.5f);
|
||||||
protected:
|
protected:
|
||||||
device_set device;
|
device_handle device;
|
||||||
renderer_buffer_desc desc;
|
renderer_buffer_desc desc;
|
||||||
vk::Buffer buffer;
|
vk::Buffer buffer;
|
||||||
vk::DeviceMemory memory;
|
vk::DeviceMemory memory;
|
||||||
|
@ -12,7 +12,7 @@ std::unique_ptr<buffer_memory_strategy> buffer_memory_strategy::create(vk::Memor
|
|||||||
throw std::runtime_error("Unsupported memory property flags");
|
throw std::runtime_error("Unsupported memory property flags");
|
||||||
}
|
}
|
||||||
|
|
||||||
void host_visible_strategy::copy_from(const device_set& in_device, vk::Buffer in_buffer, const vk::DeviceMemory in_device_memory,
|
void host_visible_strategy::copy_from(const device_handle& in_device, vk::Buffer in_buffer, const vk::DeviceMemory in_device_memory,
|
||||||
const void* in_data, const vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) {
|
const void* in_data, const vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) {
|
||||||
void* mapped = in_device->mapMemory(in_device_memory, 0, in_size);
|
void* mapped = in_device->mapMemory(in_device_memory, 0, in_size);
|
||||||
std::memcpy(mapped, in_data, in_size);
|
std::memcpy(mapped, in_data, in_size);
|
||||||
@ -26,7 +26,7 @@ void host_visible_strategy::copy_from(const device_set& in_device, vk::Buffer in
|
|||||||
in_device->unmapMemory(in_device_memory);
|
in_device->unmapMemory(in_device_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void device_local_strategy::copy_from(const device_set& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory,
|
void device_local_strategy::copy_from(const device_handle& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory,
|
||||||
const void* in_data, const vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) {
|
const void* in_data, const vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) {
|
||||||
|
|
||||||
// 创建暂存缓冲区
|
// 创建暂存缓冲区
|
||||||
|
@ -8,7 +8,7 @@ class buffer_memory_strategy {
|
|||||||
public:
|
public:
|
||||||
virtual ~buffer_memory_strategy() = default;
|
virtual ~buffer_memory_strategy() = default;
|
||||||
|
|
||||||
virtual void copy_from(const device_set& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory,
|
virtual void copy_from(const device_handle& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory,
|
||||||
const void* in_data, vk::DeviceSize in_size,
|
const void* in_data, vk::DeviceSize in_size,
|
||||||
vk::CommandBuffer in_command_buffer) = 0;
|
vk::CommandBuffer in_command_buffer) = 0;
|
||||||
|
|
||||||
@ -17,10 +17,10 @@ public:
|
|||||||
|
|
||||||
class host_visible_strategy : public buffer_memory_strategy {
|
class host_visible_strategy : public buffer_memory_strategy {
|
||||||
public:
|
public:
|
||||||
virtual void copy_from(const device_set& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory, const void* in_data, vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) override;
|
virtual void copy_from(const device_handle& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory, const void* in_data, vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class device_local_strategy : public buffer_memory_strategy {
|
class device_local_strategy : public buffer_memory_strategy {
|
||||||
public:
|
public:
|
||||||
virtual void copy_from(const device_set& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory, const void* in_data, vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) override;
|
virtual void copy_from(const device_handle& in_device, vk::Buffer in_buffer, vk::DeviceMemory in_device_memory, const void* in_data, vk::DeviceSize in_size, vk::CommandBuffer in_command_buffer) override;
|
||||||
};
|
};
|
||||||
|
175
src/core/renderer/renderer_swapchain.cpp
Normal file
175
src/core/renderer/renderer_swapchain.cpp
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
#include "renderer_swapchain.h"
|
||||||
|
|
||||||
|
// std::string to_string(const vk::Extent2D& in) {
|
||||||
|
// return fmt::format("Extent2D: {}x{}", in.width, in.height);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::string to_string(const vk::SwapchainCreateInfoKHR& in) {
|
||||||
|
// // 格式化字符串
|
||||||
|
// std::string result = fmt::format("SwapchainCreateInfoKHR:\n"
|
||||||
|
// " surface: {}\n"
|
||||||
|
// " minImageCount: {}\n"
|
||||||
|
// " imageFormat: {}\n"
|
||||||
|
// " imageColorSpace: {}\n"
|
||||||
|
// " imageExtent: {}\n"
|
||||||
|
// " imageArrayLayers: {}\n"
|
||||||
|
// " imageUsage: {}\n"
|
||||||
|
// " presentMode: {}\n"
|
||||||
|
// " preTransform: {}\n"
|
||||||
|
// " compositeAlpha: {}\n"
|
||||||
|
// " clipped: {}\n",
|
||||||
|
// in.surface,
|
||||||
|
// in.minImageCount,
|
||||||
|
// vk::to_string(in.imageFormat),
|
||||||
|
// vk::to_string(in.imageColorSpace),
|
||||||
|
// to_string(in.imageExtent),
|
||||||
|
// in.imageArrayLayers,
|
||||||
|
// vk::to_string(in.imageUsage),
|
||||||
|
// vk::to_string(in.presentMode),
|
||||||
|
// vk::to_string(in.preTransform),
|
||||||
|
// vk::to_string(in.compositeAlpha),
|
||||||
|
// in.clipped);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
bool renderer_swapchain::init_swapchain(const device_handle& in_device, const vk::SurfaceKHR& in_surface, const create_info& in_info) {
|
||||||
|
device = in_device;
|
||||||
|
surface = in_surface;
|
||||||
|
info = in_info;
|
||||||
|
// 获取交换链支持的信息
|
||||||
|
const auto& surface_capabilities = device.physical_device.getSurfaceCapabilitiesKHR(in_surface);
|
||||||
|
|
||||||
|
// 验证并调整图像数量
|
||||||
|
uint32_t image_count = std::max(in_info.min_image_count,
|
||||||
|
surface_capabilities.minImageCount);
|
||||||
|
if (surface_capabilities.maxImageCount > 0) {
|
||||||
|
image_count = std::clamp(image_count,
|
||||||
|
surface_capabilities.minImageCount,
|
||||||
|
surface_capabilities.maxImageCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证并调整图像格式
|
||||||
|
auto surface_formats = device.physical_device.getSurfaceFormatsKHR(in_surface);
|
||||||
|
if (surface_formats.empty()) {
|
||||||
|
spdlog::error("获取表面格式失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (surface_formats.size() == 1 && surface_formats[0].format == vk::Format::eUndefined) {
|
||||||
|
info.format = vk::Format::eB8G8R8A8Srgb;
|
||||||
|
info.color_space = vk::ColorSpaceKHR::eSrgbNonlinear;
|
||||||
|
spdlog::warn("表面格式未指定,使用默认格式 {} {}", vk::to_string(info.format), vk::to_string(info.color_space));
|
||||||
|
} else {
|
||||||
|
bool found = false;
|
||||||
|
for (const auto& format : surface_formats) {
|
||||||
|
if (format.format == info.format && format.colorSpace == info.color_space) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
info.format = surface_formats[0].format;
|
||||||
|
info.color_space = surface_formats[0].colorSpace;
|
||||||
|
spdlog::warn("请求的表面格式不支持,使用默认格式 {} {}", vk::to_string(info.format), vk::to_string(info.color_space));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证并调整呈现模式
|
||||||
|
auto present_modes = device.physical_device.getSurfacePresentModesKHR(in_surface);
|
||||||
|
if (present_modes.empty()) {
|
||||||
|
spdlog::error("获取呈现模式失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (std::ranges::find(present_modes, info.present_mode) == present_modes.end()) {
|
||||||
|
info.present_mode = vk::PresentModeKHR::eFifo;
|
||||||
|
spdlog::warn("请求的呈现模式不支持,使用默认呈现模式 Fifo");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证并调整交换链尺寸
|
||||||
|
info.extent = std::clamp(info.extent,
|
||||||
|
surface_capabilities.minImageExtent,
|
||||||
|
surface_capabilities.maxImageExtent);
|
||||||
|
|
||||||
|
// 验证并调整图像用途
|
||||||
|
if ((surface_capabilities.supportedUsageFlags & info.image_usage) != info.image_usage) {
|
||||||
|
info.image_usage = vk::ImageUsageFlagBits::eColorAttachment;
|
||||||
|
spdlog::warn("请求的图像用途不支持,使用默认图像用途 ColorAttachment");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证并调整合成 alpha
|
||||||
|
if (!(surface_capabilities.supportedCompositeAlpha & vk::CompositeAlphaFlagBitsKHR::eOpaque)) {
|
||||||
|
spdlog::warn("不支持不透明合成 alpha");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建交换链信息
|
||||||
|
vk::SwapchainCreateInfoKHR create_info{};
|
||||||
|
create_info.surface = surface;
|
||||||
|
create_info.minImageCount = image_count;
|
||||||
|
create_info.imageFormat = info.format;
|
||||||
|
create_info.imageColorSpace = info.color_space;
|
||||||
|
create_info.imageExtent = info.extent;
|
||||||
|
create_info.imageArrayLayers = 1;
|
||||||
|
create_info.imageUsage = info.image_usage;
|
||||||
|
create_info.imageSharingMode = vk::SharingMode::eExclusive;
|
||||||
|
create_info.presentMode = info.present_mode;
|
||||||
|
create_info.preTransform = surface_capabilities.currentTransform;
|
||||||
|
create_info.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque;
|
||||||
|
create_info.clipped = VK_TRUE;
|
||||||
|
create_info.imageExtent = info.extent;
|
||||||
|
|
||||||
|
// 创建交换链
|
||||||
|
swapchain = device->createSwapchainKHR(create_info);
|
||||||
|
if (!swapchain) {
|
||||||
|
spdlog::error("创建交换链失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
images = device->getSwapchainImagesKHR(swapchain);
|
||||||
|
if (images.empty()) {
|
||||||
|
spdlog::error("获取交换链图像失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建图像视图
|
||||||
|
return create_image_views(device.device, in_info.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renderer_swapchain::create_image_views(const vk::Device& device, vk::Format format) {
|
||||||
|
image_views.resize(images.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < images.size(); i++) {
|
||||||
|
vk::ImageViewCreateInfo view_info{};
|
||||||
|
view_info.image = images[i];
|
||||||
|
view_info.viewType = vk::ImageViewType::e2D;
|
||||||
|
view_info.format = format;
|
||||||
|
view_info.components.r = vk::ComponentSwizzle::eIdentity;
|
||||||
|
view_info.components.g = vk::ComponentSwizzle::eIdentity;
|
||||||
|
view_info.components.b = vk::ComponentSwizzle::eIdentity;
|
||||||
|
view_info.components.a = vk::ComponentSwizzle::eIdentity;
|
||||||
|
view_info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
|
||||||
|
view_info.subresourceRange.baseMipLevel = 0;
|
||||||
|
view_info.subresourceRange.levelCount = 1;
|
||||||
|
view_info.subresourceRange.baseArrayLayer = 0;
|
||||||
|
view_info.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
auto new_view = device.createImageView(view_info);
|
||||||
|
if (new_view)
|
||||||
|
image_views[i] = new_view;
|
||||||
|
else
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ERROR:
|
||||||
|
spdlog::error("创建图像视图失败");
|
||||||
|
for (const auto view: image_views) { device.destroyImageView(view); }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderer_swapchain::cleanup() {
|
||||||
|
if (device) {
|
||||||
|
for (const auto& view : image_views) {
|
||||||
|
device->destroyImageView(view);
|
||||||
|
}
|
||||||
|
device->destroySwapchainKHR(swapchain);
|
||||||
|
}
|
||||||
|
}
|
52
src/core/renderer/renderer_swapchain.h
Normal file
52
src/core/renderer/renderer_swapchain.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include "renderer_types.h"
|
||||||
|
|
||||||
|
class renderer_swapchain {
|
||||||
|
public:
|
||||||
|
struct create_info {
|
||||||
|
vk::PresentModeKHR present_mode = vk::PresentModeKHR::eMailbox; // 呈现模式
|
||||||
|
vk::Format format = vk::Format::eB8G8R8A8Srgb; // 请求的图像格式
|
||||||
|
vk::ColorSpaceKHR color_space = vk::ColorSpaceKHR::eSrgbNonlinear; // 色彩空间
|
||||||
|
vk::ImageUsageFlags image_usage = vk::ImageUsageFlagBits::eColorAttachment; // 图像用途
|
||||||
|
vk::Extent2D extent = vk::Extent2D(800, 600); // 交换链图像大小
|
||||||
|
uint32_t min_image_count = 2; // 最小缓冲区数量
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer_swapchain() {
|
||||||
|
}
|
||||||
|
|
||||||
|
~renderer_swapchain() {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resize(const vk::Extent2D& in_size) {
|
||||||
|
cleanup();
|
||||||
|
info.extent = in_size;
|
||||||
|
return init_swapchain(device, surface, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const auto& get_swapchain() const { return swapchain; }
|
||||||
|
[[nodiscard]] const auto& get_images() const { return images; }
|
||||||
|
[[nodiscard]] const auto& get_image_views() const { return image_views; }
|
||||||
|
[[nodiscard]] const auto& get_create_info() const { return info; }
|
||||||
|
[[nodiscard]] const auto& get_surface() const { return surface; }
|
||||||
|
[[nodiscard]] const auto& get_device() const { return device; }
|
||||||
|
|
||||||
|
bool init_swapchain(const device_handle& in_device, const vk::SurfaceKHR& in_surface, const create_info& in_info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool create_image_views(const vk::Device& device, vk::Format format);
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
private:
|
||||||
|
device_handle device;
|
||||||
|
create_info info;
|
||||||
|
vk::SurfaceKHR surface;
|
||||||
|
vk::SwapchainKHR swapchain;
|
||||||
|
std::vector<vk::Image> images;
|
||||||
|
std::vector<vk::ImageView> image_views;
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
struct device_set {
|
struct device_handle {
|
||||||
vk::PhysicalDevice physical_device;
|
vk::PhysicalDevice physical_device;
|
||||||
vk::Device device;
|
vk::Device device;
|
||||||
|
|
||||||
@ -18,6 +18,13 @@ struct device_set {
|
|||||||
physical_device = in_physical_device;
|
physical_device = in_physical_device;
|
||||||
device = physical_device.createDevice(in_create_info);
|
device = physical_device.createDevice(in_create_info);
|
||||||
}
|
}
|
||||||
|
void destroy_device() {
|
||||||
|
if (device) {
|
||||||
|
device.destroy();
|
||||||
|
device = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 获取物理设备GUID
|
// 获取物理设备GUID
|
||||||
[[nodiscard]] uint32_t get_physical_device_id() const;
|
[[nodiscard]] uint32_t get_physical_device_id() const;
|
||||||
// 获取物理设备名称
|
// 获取物理设备名称
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
#include "window/renderer_window.h"
|
|
||||||
|
|
||||||
#include "LLGL/Platform/MacOS/MacOSNativeHandle.h"
|
|
||||||
|
|
||||||
void* renderer_window::get_native_handle() const {
|
|
||||||
if (auto surface = get_surface()) {
|
|
||||||
LLGL::NativeHandle native_handle;
|
|
||||||
surface->GetNativeHandle(&native_handle, sizeof(LLGL::NativeHandle));
|
|
||||||
return native_handle.responder;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
@ -3,6 +3,7 @@
|
|||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include "window_manager.h"
|
#include "window_manager.h"
|
||||||
|
#include <GLFW/glfw3native.h>
|
||||||
|
|
||||||
renderer_window::renderer_window(const window_desc& in_desc) {
|
renderer_window::renderer_window(const window_desc& in_desc) {
|
||||||
glfwWindowHint(GLFW_RESIZABLE, in_desc.resizable);
|
glfwWindowHint(GLFW_RESIZABLE, in_desc.resizable);
|
||||||
@ -37,6 +38,13 @@ renderer_window::renderer_window(const window_desc& in_desc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderer_window::~renderer_window() {
|
renderer_window::~renderer_window() {
|
||||||
|
delete swapchain;
|
||||||
|
if (surface) {
|
||||||
|
const auto renderer = aorii::get_renderer();
|
||||||
|
if (renderer) {
|
||||||
|
renderer->destroy_surface(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_window::set_title(const std::wstring& in_title) const {
|
void renderer_window::set_title(const std::wstring& in_title) const {
|
||||||
@ -58,7 +66,7 @@ bool renderer_window::create_surface() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool renderer_window::create_swap_chain(vk::SwapchainCreateInfoKHR in_create_info) {
|
bool renderer_window::create_swap_chain(const renderer_swapchain::create_info& in_create_info) {
|
||||||
const auto renderer = aorii::get_renderer();
|
const auto renderer = aorii::get_renderer();
|
||||||
if (!renderer)
|
if (!renderer)
|
||||||
return false;
|
return false;
|
||||||
@ -66,23 +74,42 @@ bool renderer_window::create_swap_chain(vk::SwapchainCreateInfoKHR in_create_inf
|
|||||||
spdlog::error("窗口表面未创建");
|
spdlog::error("窗口表面未创建");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
in_create_info.setSurface(surface);
|
|
||||||
swap_chain = renderer->create_swap_chain(in_create_info);
|
const auto& main_device = renderer->get_main_device();
|
||||||
if (!swap_chain) {
|
auto temp_swapchain_info = in_create_info;
|
||||||
|
temp_swapchain_info.extent = get_size();
|
||||||
|
|
||||||
|
swapchain = new renderer_swapchain();
|
||||||
|
if (!swapchain->init_swapchain(main_device, surface, temp_swapchain_info)) {
|
||||||
spdlog::error("创建交换链失败");
|
spdlog::error("创建交换链失败");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !AORII_MACOS
|
|
||||||
void* renderer_window::get_native_handle() const {
|
void* renderer_window::get_native_handle() const {
|
||||||
|
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||||
|
return glfwGetWin32Window(window);
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||||
|
return glfwGetCocoaWindow(window);
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_X11)
|
||||||
|
return reinterpret_cast<void*>(
|
||||||
|
static_cast<uintptr_t>(glfwGetX11Window(window)));
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||||
|
return glfwGetWaylandWindow(window);
|
||||||
|
#elif defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||||
|
return static_cast<void*>(glfwGetEGLDisplay(window));
|
||||||
|
#else
|
||||||
|
static_assert(false, "No native platform window implementation available");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void renderer_window::on_resize(int in_width, int in_height) {
|
void renderer_window::on_resize(int in_width, int in_height) {
|
||||||
spdlog::info("窗口大小变更:{}x{}", in_width, in_height);
|
spdlog::info("窗口大小变更:{}x{}", in_width, in_height);
|
||||||
|
if (swapchain) {
|
||||||
|
swapchain->resize({static_cast<uint32_t>(in_width), static_cast<uint32_t>(in_height)});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_window::on_glfw_close() {
|
void renderer_window::on_glfw_close() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "renderer/renderer.h"
|
#include "renderer/renderer.h"
|
||||||
|
#include "renderer/renderer_swapchain.h"
|
||||||
|
|
||||||
#include "vulkan/vulkan.hpp"
|
#include "vulkan/vulkan.hpp"
|
||||||
|
|
||||||
@ -47,14 +48,14 @@ public:
|
|||||||
|
|
||||||
bool create_surface();
|
bool create_surface();
|
||||||
[[nodiscard]] auto get_surface() const { return surface; }
|
[[nodiscard]] auto get_surface() const { return surface; }
|
||||||
bool create_swap_chain(vk::SwapchainCreateInfoKHR in_create_info);
|
bool create_swap_chain(const renderer_swapchain::create_info& in_create_info);
|
||||||
[[nodiscard]] auto get_swap_chain() const { return swap_chain; }
|
[[nodiscard]] auto get_swap_chain() const { return swapchain; }
|
||||||
[[nodiscard]] void* get_native_handle() const;
|
[[nodiscard]] void* get_native_handle() const;
|
||||||
protected:
|
protected:
|
||||||
virtual void on_resize(int in_width, int in_height);
|
virtual void on_resize(int in_width, int in_height);
|
||||||
virtual void on_glfw_close();
|
virtual void on_glfw_close();
|
||||||
private:
|
private:
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
vk::SwapchainKHR swap_chain;
|
renderer_swapchain* swapchain;
|
||||||
vk::SurfaceKHR surface;
|
vk::SurfaceKHR surface;
|
||||||
};
|
};
|
||||||
|
@ -42,7 +42,7 @@ std::weak_ptr<renderer_window> window_manager::create_window(const window_desc&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void window_manager::destroy_window(renderer_window* in_window) {
|
void window_manager::destroy_window(renderer_window* in_window) {
|
||||||
auto it = std::ranges::find_if(windows, [in_window](const auto& window) {
|
const auto it = std::ranges::find_if(windows, [in_window](const auto& window) {
|
||||||
return window.get() == in_window;
|
return window.get() == in_window;
|
||||||
});
|
});
|
||||||
if (it != windows.end()) {
|
if (it != windows.end()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user