Вынес работу с VpPhysicalDevice в отдельный класс
This commit is contained in:
@@ -29,134 +29,21 @@ UwURenderEngine::SwapchainSupportDetails UwURenderEngine::query_swapchain_detail
|
||||
{
|
||||
SwapchainSupportDetails details;
|
||||
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_, surface_.get_native(), &details.capabilities);
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_.get_native(), surface_.get_native(), &details.capabilities);
|
||||
|
||||
uint32_t surface_format_cnt = 0;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_.get_native(), &surface_format_cnt, nullptr))
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_.get_native(), surface_.get_native(), &surface_format_cnt, nullptr))
|
||||
details.formats.resize(surface_format_cnt);
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_.get_native(), &surface_format_cnt, details.formats.data()))
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_.get_native(), surface_.get_native(), &surface_format_cnt, details.formats.data()))
|
||||
|
||||
uint32_t present_modes_cnt = 0;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_.get_native(), &present_modes_cnt, nullptr))
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_.get_native(), surface_.get_native(), &present_modes_cnt, nullptr))
|
||||
details.present_modes.resize(surface_format_cnt);
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_.get_native(), &present_modes_cnt, details.present_modes.data()))
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_.get_native(), surface_.get_native(), &present_modes_cnt, details.present_modes.data()))
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface)
|
||||
{
|
||||
VkPhysicalDeviceProperties device_properties;
|
||||
VkPhysicalDeviceFeatures device_features;
|
||||
vkGetPhysicalDeviceProperties(device, &device_properties);
|
||||
vkGetPhysicalDeviceFeatures(device, &device_features);
|
||||
|
||||
try {
|
||||
// Ловить исключения имеет смысыл только здесь
|
||||
find_queue_family_indices(device, surface);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return check_device_extensions_support(device);
|
||||
}
|
||||
|
||||
bool UwURenderEngine::check_device_extensions_support(VkPhysicalDevice device)
|
||||
{
|
||||
uint32_t extension_count;
|
||||
VK_CHECK(vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, nullptr))
|
||||
std::vector<VkExtensionProperties> available_extensions(extension_count);
|
||||
VK_CHECK(vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, available_extensions.data()))
|
||||
|
||||
for (const auto& extension : deviceExtensions)
|
||||
{
|
||||
bool isFind = false;
|
||||
for (const auto& i : available_extensions)
|
||||
{
|
||||
if (std::strcmp(i.extensionName, extension) == 0)
|
||||
{
|
||||
isFind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFind)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
UwURenderEngine::QueueFamilyIndices UwURenderEngine::find_queue_family_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface)
|
||||
{
|
||||
QueueFamilyIndices queue_family_indices;
|
||||
|
||||
uint32_t queueFamilyCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, nullptr);
|
||||
std::vector<VkQueueFamilyProperties> family_properties(queueFamilyCount);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, family_properties.data());
|
||||
|
||||
// Find graphics
|
||||
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
||||
{
|
||||
if (family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
queue_family_indices.graphics_family = i;
|
||||
queue_family_indices.is_find_graphics_family = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (queue_family_indices.is_find_graphics_family == false)
|
||||
throw std::runtime_error("Failed to find a graphics queue family");
|
||||
|
||||
// Find present
|
||||
VkBool32 present_support = false;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_indices.graphics_family, surface, &present_support))
|
||||
// Если графическая очередь поддерживет презентацию кадров, то используем её
|
||||
if (present_support == VK_TRUE)
|
||||
{
|
||||
queue_family_indices.present_family = queue_family_indices.graphics_family;
|
||||
queue_family_indices.is_find_present_family = true;
|
||||
}
|
||||
// иначе ищем другую подходящую очередь
|
||||
else
|
||||
{
|
||||
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
||||
{
|
||||
present_support = false;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &present_support))
|
||||
if (present_support == VK_TRUE)
|
||||
{
|
||||
queue_family_indices.present_family = i;
|
||||
queue_family_indices.is_find_present_family = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (queue_family_indices.is_find_present_family == false)
|
||||
throw std::runtime_error("Failed to find a present queue family");
|
||||
|
||||
// С начала пытаемся найти очередь специалезированную
|
||||
// для копирования отличную от графической
|
||||
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
||||
{
|
||||
if (i == queue_family_indices.graphics_family)
|
||||
continue;
|
||||
if (family_properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT)
|
||||
{
|
||||
queue_family_indices.transfer_family = i;
|
||||
queue_family_indices.is_find_transfer_family = true;
|
||||
}
|
||||
}
|
||||
// Если не находим, то используем графическую
|
||||
if (queue_family_indices.is_find_transfer_family == false)
|
||||
{
|
||||
queue_family_indices.transfer_family = queue_family_indices.graphics_family;
|
||||
queue_family_indices.is_find_transfer_family = true;
|
||||
}
|
||||
return queue_family_indices;
|
||||
}
|
||||
|
||||
VkSurfaceFormatKHR UwURenderEngine::choose_surface_format(const std::vector<VkSurfaceFormatKHR>& surface_formats)
|
||||
{
|
||||
for (const auto& i : surface_formats)
|
||||
@@ -189,33 +76,9 @@ VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) co
|
||||
return shader_module;
|
||||
}
|
||||
|
||||
void UwURenderEngine::pick_physical_device()
|
||||
{
|
||||
uint32_t device_count = 0;
|
||||
std::vector<VkPhysicalDevice> devices;
|
||||
VK_CHECK(vkEnumeratePhysicalDevices(instance_.get_native(), &device_count, nullptr))
|
||||
devices.resize(device_count);
|
||||
VK_CHECK(vkEnumeratePhysicalDevices(instance_.get_native(), &device_count, devices.data()))
|
||||
|
||||
for (const auto& device : devices)
|
||||
{
|
||||
if (is_device_suitable(device, surface_.get_native()))
|
||||
{
|
||||
physical_device_ = device;
|
||||
VkPhysicalDeviceProperties device_properties;
|
||||
vkGetPhysicalDeviceProperties(physical_device_, &device_properties);
|
||||
Loging::Log("Using device: " + std::string(device_properties.deviceName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (VK_NULL_HANDLE == physical_device_)
|
||||
throw std::runtime_error("No suitable device found");
|
||||
}
|
||||
|
||||
void UwURenderEngine::create_logical_device()
|
||||
{
|
||||
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
||||
VkObjects::PhysicalDevice::QueueFamilyIndices indices = physical_device_.get_queue_family_indices();
|
||||
|
||||
VkPhysicalDeviceFeatures device_features{};
|
||||
|
||||
@@ -254,7 +117,7 @@ void UwURenderEngine::create_logical_device()
|
||||
device_create_info.ppEnabledLayerNames = nullptr;
|
||||
|
||||
#endif
|
||||
VK_CHECK(vkCreateDevice(physical_device_, &device_create_info, nullptr, &device_))
|
||||
VK_CHECK(vkCreateDevice(physical_device_.get_native(), &device_create_info, nullptr, &device_))
|
||||
vkGetDeviceQueue(device_, indices.graphics_family, 0, &graphics_queue_);
|
||||
vkGetDeviceQueue(device_, indices.present_family, 0, &present_queue_);
|
||||
vkGetDeviceQueue(device_, indices.transfer_family, 0, &transfer_queue_);
|
||||
@@ -286,7 +149,7 @@ void UwURenderEngine::create_swapchain()
|
||||
swapchain_create_info.clipped = VK_TRUE;
|
||||
swapchain_create_info.oldSwapchain = VK_NULL_HANDLE;
|
||||
|
||||
QueueFamilyIndices family_indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
||||
VkObjects::PhysicalDevice::QueueFamilyIndices family_indices = physical_device_.get_queue_family_indices();
|
||||
const std::set<uint32_t> queue_family_indices = { family_indices.graphics_family,
|
||||
family_indices.present_family,
|
||||
family_indices.transfer_family };
|
||||
@@ -407,12 +270,12 @@ void UwURenderEngine::create_uniform_buffers()
|
||||
uniform_buffers_memory_.resize(swapchain_images_.size());
|
||||
uniform_buffers_mapped_.resize(swapchain_images_.size());
|
||||
|
||||
std::vector<uint32_t> arr_indices = get_unique_family_indices(find_queue_family_indices(physical_device_, surface_.get_native()));
|
||||
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
||||
for (size_t i = 0; i < swapchain_images_.size(); ++i)
|
||||
{
|
||||
const VkDeviceSize size = sizeof(UniformBufferObject);
|
||||
uniform_buffers_[i] = DeviceFunctions::create_buffer(device_, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, arr_indices);
|
||||
uniform_buffers_memory_[i] = DeviceFunctions::allocate_device_memory(physical_device_, device_, uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
uniform_buffers_memory_[i] = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_, uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
vkBindBufferMemory(device_, uniform_buffers_[i], uniform_buffers_memory_[i], 0);
|
||||
|
||||
vkMapMemory(device_, uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]);
|
||||
@@ -631,7 +494,7 @@ void UwURenderEngine::create_framebuffers()
|
||||
|
||||
void UwURenderEngine::create_command_pool()
|
||||
{
|
||||
QueueFamilyIndices queue_family_indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
||||
VkObjects::PhysicalDevice::QueueFamilyIndices queue_family_indices = physical_device_.get_queue_family_indices();
|
||||
|
||||
VkCommandPoolCreateInfo command_pool_info{};
|
||||
command_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
@@ -641,36 +504,23 @@ void UwURenderEngine::create_command_pool()
|
||||
VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_))
|
||||
}
|
||||
|
||||
std::vector<uint32_t> UwURenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices)
|
||||
{
|
||||
std::set<uint32_t> set_indices = {indices.graphics_family,
|
||||
indices.present_family,
|
||||
indices.transfer_family};
|
||||
|
||||
std::vector<uint32_t> arr_indices;
|
||||
arr_indices.reserve(set_indices.size());
|
||||
for (auto& i : set_indices)
|
||||
arr_indices.push_back(i);
|
||||
return arr_indices;
|
||||
}
|
||||
|
||||
void UwURenderEngine::allocate_vertex_buffer()
|
||||
{
|
||||
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
||||
VkObjects::PhysicalDevice::QueueFamilyIndices indices = physical_device_.get_queue_family_indices();
|
||||
|
||||
|
||||
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
|
||||
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
||||
std::vector<uint32_t> transfer_index = {indices.transfer_family};
|
||||
|
||||
VkDeviceSize size_buffer = sizeof(vertices_[0]) * vertices_.size();
|
||||
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
transfer_index);
|
||||
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
|
||||
physical_device_, device_, staging_buffer,
|
||||
physical_device_.get_native(), device_, staging_buffer,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
vertex_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, arr_indices);
|
||||
vertex_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_, device_, vertex_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
vertex_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_, vertex_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
VK_CHECK(vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0))
|
||||
VK_CHECK(vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0))
|
||||
@@ -688,19 +538,15 @@ void UwURenderEngine::allocate_vertex_buffer()
|
||||
|
||||
void UwURenderEngine::allocate_index_buffer()
|
||||
{
|
||||
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
||||
std::set<uint32_t> set_indices = {indices.graphics_family,
|
||||
indices.present_family,
|
||||
indices.transfer_family};
|
||||
|
||||
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
|
||||
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
||||
VkObjects::PhysicalDevice::QueueFamilyIndices indices = physical_device_.get_queue_family_indices();
|
||||
std::vector<uint32_t> transfer_index = {indices.transfer_family};
|
||||
|
||||
VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size();
|
||||
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
transfer_index);
|
||||
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
|
||||
physical_device_, device_, staging_buffer,
|
||||
physical_device_.get_native(), device_, staging_buffer,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0);
|
||||
|
||||
@@ -710,7 +556,7 @@ void UwURenderEngine::allocate_index_buffer()
|
||||
vkUnmapMemory(device_, staging_buffer_memory);
|
||||
|
||||
index_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, arr_indices);
|
||||
index_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_, device_, index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
index_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), device_, index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
vkBindBufferMemory(device_, index_buffer_, index_buffer_memory_, 0);
|
||||
|
||||
DeviceFunctions::device_memcpy(device_, indices.transfer_family,staging_buffer, index_buffer_, size_buffer);
|
||||
@@ -875,9 +721,9 @@ void UwURenderEngine::draw_frame()
|
||||
UwURenderEngine::UwURenderEngine(CoreInstance& core):RenderEngineBase(core),
|
||||
instance_(core),
|
||||
surface_(instance_, get_window()),
|
||||
physical_device_(instance_, surface_, deviceExtensions),
|
||||
core_(core)
|
||||
{
|
||||
pick_physical_device();
|
||||
create_logical_device();
|
||||
create_swapchain();
|
||||
create_image_views();
|
||||
@@ -895,7 +741,7 @@ core_(core)
|
||||
create_sync_objects();
|
||||
|
||||
garbage_collector_.reset(new GPU_GarbageCollector(device_));
|
||||
model_manager_.reset(new ModelManager(physical_device_, device_));
|
||||
model_manager_.reset(new ModelManager(physical_device_.get_native(), device_));
|
||||
}
|
||||
|
||||
UwURenderEngine::~UwURenderEngine()
|
||||
|
||||
Reference in New Issue
Block a user