mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 15:24:34 +00:00
WIP queue rewrite
This commit is contained in:
parent
7d2402ba2d
commit
5375504bb3
@ -460,63 +460,53 @@ bool supports_features (VkPhysicalDeviceFeatures supported, VkPhysicalDeviceFeat
|
|||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
QueueFamilies find_queue_families (VkPhysicalDevice phys_device, VkSurfaceKHR surface) {
|
int get_graphics_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
|
for (int i = 0; i < families.size (); i++) {
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties, phys_device);
|
if (families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) return i;
|
||||||
|
}
|
||||||
QueueFamilies families;
|
return -1;
|
||||||
int dedicated_compute = -1;
|
}
|
||||||
int dedicated_transfer = -1;
|
int get_distinct_compute_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
|
for (int i = 0; i < families.size (); i++) {
|
||||||
for (int i = 0; i < queue_families.size (); i++) {
|
if ((families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
|
||||||
auto& queueFlags = queue_families[i].queueFlags;
|
((families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0))
|
||||||
if (queueFlags & VK_QUEUE_GRAPHICS_BIT) families.graphics = i;
|
return i;
|
||||||
if (queueFlags & VK_QUEUE_COMPUTE_BIT) families.compute = i;
|
}
|
||||||
if (queueFlags & VK_QUEUE_TRANSFER_BIT) families.transfer = i;
|
return -1;
|
||||||
if (queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) families.sparse = i;
|
}
|
||||||
|
int get_distinct_transfer_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
// compute that isn't graphics
|
for (int i = 0; i < families.size (); i++) {
|
||||||
if (queueFlags & VK_QUEUE_COMPUTE_BIT && ((queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0))
|
if ((families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) &&
|
||||||
dedicated_compute = i;
|
((families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0))
|
||||||
|
return true;
|
||||||
// transfer that isn't computer or graphics
|
}
|
||||||
if (queueFlags & VK_QUEUE_TRANSFER_BIT && ((queueFlags & VK_QUEUE_COMPUTE_BIT) == 0) &&
|
return -1;
|
||||||
((queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0))
|
}
|
||||||
dedicated_transfer = i;
|
int get_present_queue_index (VkPhysicalDevice const phys_device,
|
||||||
|
VkSurfaceKHR const surface,
|
||||||
|
std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
|
for (int i = 0; i < families.size (); i++) {
|
||||||
VkBool32 presentSupport = false;
|
VkBool32 presentSupport = false;
|
||||||
if (surface != VK_NULL_HANDLE) {
|
if (surface != VK_NULL_HANDLE) {
|
||||||
VkResult res = vkGetPhysicalDeviceSurfaceSupportKHR (phys_device, i, surface, &presentSupport);
|
VkResult res = vkGetPhysicalDeviceSurfaceSupportKHR (phys_device, i, surface, &presentSupport);
|
||||||
}
|
}
|
||||||
if (presentSupport == true) families.present = i;
|
if (presentSupport == true) return i;
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
if (dedicated_compute != -1) families.compute = dedicated_compute;
|
|
||||||
if (dedicated_transfer != -1) families.transfer = dedicated_transfer;
|
|
||||||
|
|
||||||
// compute and transfer always supported on the graphics family
|
|
||||||
if (families.compute != -1 && queue_families[families.graphics].queueFlags & VK_QUEUE_COMPUTE_BIT)
|
|
||||||
families.compute = families.graphics;
|
|
||||||
if (families.transfer != -1 && queue_families[families.graphics].queueFlags & VK_QUEUE_TRANSFER_BIT)
|
|
||||||
families.transfer = families.graphics;
|
|
||||||
|
|
||||||
families.count_graphics = queue_families[families.graphics].queueCount;
|
|
||||||
families.count_transfer = queue_families[families.transfer].queueCount;
|
|
||||||
families.count_compute = queue_families[families.compute].queueCount;
|
|
||||||
if (families.sparse != -1) families.count_sparse = queue_families[families.sparse].queueCount;
|
|
||||||
return families;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkPhysicalDevice phys_device) {
|
PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkPhysicalDevice phys_device) {
|
||||||
Suitable suitable = Suitable::yes;
|
Suitable suitable = Suitable::yes;
|
||||||
|
|
||||||
QueueFamilies indices = find_queue_families (phys_device, info.surface);
|
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties, phys_device);
|
||||||
|
bool dedicated_compute = get_distinct_compute_queue_index (queue_families);
|
||||||
|
bool dedicated_transfer = get_distinct_transfer_queue_index (queue_families);
|
||||||
|
bool present_queue = get_present_queue_index (phys_device, info.surface, queue_families);
|
||||||
|
|
||||||
if (criteria.require_dedicated_compute_queue && indices.graphics != indices.compute)
|
if (criteria.require_dedicated_compute_queue && !dedicated_compute) suitable = Suitable::no;
|
||||||
suitable = Suitable::no;
|
if (criteria.require_dedicated_transfer_queue && !dedicated_transfer) suitable = Suitable::no;
|
||||||
if (criteria.require_dedicated_transfer_queue && indices.graphics != indices.transfer)
|
if (criteria.require_present && !present_queue) suitable = Suitable::no;
|
||||||
suitable = Suitable::no;
|
|
||||||
if (criteria.require_present && indices.present == -1) suitable = Suitable::no;
|
|
||||||
|
|
||||||
auto required_extensions_supported =
|
auto required_extensions_supported =
|
||||||
detail::check_device_extension_support (phys_device, criteria.required_extensions);
|
detail::check_device_extension_support (phys_device, criteria.required_extensions);
|
||||||
@ -580,9 +570,6 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkP
|
|||||||
bool required_features_supported =
|
bool required_features_supported =
|
||||||
detail::supports_features (supported_features, criteria.required_features);
|
detail::supports_features (supported_features, criteria.required_features);
|
||||||
if (!required_features_supported) suitable = Suitable::no;
|
if (!required_features_supported) suitable = Suitable::no;
|
||||||
bool desired_features_supported = detail::supports_features (supported_features, criteria.desired_features);
|
|
||||||
if (!desired_features_supported) suitable = Suitable::partial;
|
|
||||||
|
|
||||||
|
|
||||||
return suitable;
|
return suitable;
|
||||||
}
|
}
|
||||||
@ -620,15 +607,10 @@ detail::Expected<PhysicalDevice, VkResult> PhysicalDeviceSelector::select () {
|
|||||||
if (physical_device.phys_device == VK_NULL_HANDLE) {
|
if (physical_device.phys_device == VK_NULL_HANDLE) {
|
||||||
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "Failed to find a suitable GPU!" };
|
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "Failed to find a suitable GPU!" };
|
||||||
}
|
}
|
||||||
// vkGetPhysicalDeviceFeatures (physical_device.phys_device, &physical_device.features);
|
|
||||||
vkGetPhysicalDeviceProperties (physical_device.phys_device, &physical_device.properties);
|
|
||||||
vkGetPhysicalDeviceMemoryProperties (physical_device.phys_device, &physical_device.memory_properties);
|
|
||||||
|
|
||||||
physical_device.surface = info.surface;
|
physical_device.surface = info.surface;
|
||||||
physical_device.features = criteria.required_features;
|
physical_device.features = criteria.required_features;
|
||||||
|
|
||||||
physical_device.queue_family_properties = find_queue_families (physical_device.phys_device, info.surface);
|
|
||||||
|
|
||||||
physical_device.extensions_to_enable.insert (physical_device.extensions_to_enable.end (),
|
physical_device.extensions_to_enable.insert (physical_device.extensions_to_enable.end (),
|
||||||
criteria.required_extensions.begin (),
|
criteria.required_extensions.begin (),
|
||||||
criteria.required_extensions.end ());
|
criteria.required_extensions.end ());
|
||||||
@ -703,66 +685,37 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features (VkPhysica
|
|||||||
criteria.required_features = features;
|
criteria.required_features = features;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
PhysicalDeviceSelector& PhysicalDeviceSelector::set_desired_features (VkPhysicalDeviceFeatures features) {
|
|
||||||
criteria.desired_features = features;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditionally (bool unconditionally) {
|
PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditionally (bool unconditionally) {
|
||||||
criteria.use_first_gpu_unconditionally = unconditionally;
|
criteria.use_first_gpu_unconditionally = unconditionally;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Queue Selection ---- //
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---- Device ---- //
|
// ---- Device ---- //
|
||||||
|
|
||||||
void destroy_device (Device device) { vkDestroyDevice (device.device, nullptr); }
|
void destroy_device (Device device) { vkDestroyDevice (device.device, nullptr); }
|
||||||
|
|
||||||
struct QueueFamily {
|
|
||||||
int32_t family;
|
|
||||||
std::vector<float> priorities;
|
|
||||||
};
|
|
||||||
DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
|
DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
|
||||||
info.physical_device = phys_device;
|
info.physical_device = phys_device;
|
||||||
info.extensions = phys_device.extensions_to_enable;
|
info.extensions = phys_device.extensions_to_enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Expected<Device, VkResult> DeviceBuilder::build () {
|
detail::Expected<Device, VkResult> DeviceBuilder::build () {
|
||||||
auto& queue_properties = info.physical_device.queue_family_properties;
|
|
||||||
std::vector<QueueFamily> families;
|
|
||||||
|
|
||||||
families.push_back ({ queue_properties.graphics,
|
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
|
||||||
info.graphics_queue_priorities.size () == 0 ?
|
vkGetPhysicalDeviceQueueFamilyProperties, info.physical_device.phys_device);
|
||||||
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_graphics : 1, 1.0f) :
|
|
||||||
info.graphics_queue_priorities });
|
|
||||||
|
|
||||||
if (queue_properties.compute != -1 && queue_properties.compute != queue_properties.graphics) {
|
|
||||||
families.push_back ({ queue_properties.compute,
|
|
||||||
info.compute_queue_priorities.size () == 0 ?
|
|
||||||
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_compute : 1, 1.0f) :
|
|
||||||
info.compute_queue_priorities });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queue_properties.transfer != -1 && queue_properties.transfer != queue_properties.graphics &&
|
|
||||||
queue_properties.transfer != queue_properties.compute)
|
|
||||||
families.push_back ({ queue_properties.transfer,
|
|
||||||
info.transfer_queue_priorities.size () == 0 ?
|
|
||||||
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_transfer : 1, 1.0f) :
|
|
||||||
info.transfer_queue_priorities });
|
|
||||||
|
|
||||||
if (queue_properties.sparse != -1 && queue_properties.sparse != queue_properties.graphics &&
|
|
||||||
queue_properties.sparse != queue_properties.compute &&
|
|
||||||
queue_properties.sparse != queue_properties.transfer)
|
|
||||||
families.push_back ({ queue_properties.sparse,
|
|
||||||
info.sparse_queue_priorities.size () == 0 ?
|
|
||||||
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_sparse : 1, 1.0f) :
|
|
||||||
info.sparse_queue_priorities });
|
|
||||||
|
|
||||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
||||||
for (auto& queue : families) {
|
float priority = 1.0f;
|
||||||
|
for (int i = 0; i < queue_families.size (); i++) {
|
||||||
VkDeviceQueueCreateInfo queue_create_info = {};
|
VkDeviceQueueCreateInfo queue_create_info = {};
|
||||||
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
queue_create_info.queueFamilyIndex = static_cast<uint32_t> (queue.family);
|
queue_create_info.queueFamilyIndex = static_cast<uint32_t> (i);
|
||||||
queue_create_info.queueCount = queue.priorities.size ();
|
queue_create_info.queueCount = 1;
|
||||||
queue_create_info.pQueuePriorities = queue.priorities.data ();
|
queue_create_info.pQueuePriorities = &priority;
|
||||||
queueCreateInfos.push_back (queue_create_info);
|
queueCreateInfos.push_back (queue_create_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,81 +750,44 @@ template <typename T> DeviceBuilder& DeviceBuilder::add_pNext (T* structure) {
|
|||||||
info.pNext_chain.push_back (reinterpret_cast<VkBaseOutStructure*> (structure));
|
info.pNext_chain.push_back (reinterpret_cast<VkBaseOutStructure*> (structure));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
DeviceBuilder& DeviceBuilder::use_multiple_queues_per_family (bool multi_queue) {
|
|
||||||
info.use_multiple_queues_per_family = true;
|
// ---- Getting Queues ---- //
|
||||||
return *this;
|
|
||||||
|
VkQueue get_queue (VkDevice device, int32_t family) {
|
||||||
|
VkQueue out_queue;
|
||||||
|
vkGetDeviceQueue (device, family, 0, &out_queue);
|
||||||
|
return out_queue;
|
||||||
}
|
}
|
||||||
DeviceBuilder& DeviceBuilder::set_graphics_queue_priorities (std::vector<float> priorities) {
|
detail::Expected<VkQueue, VkResult> get_present_queue (Device const& device) {
|
||||||
if (info.physical_device.queue_family_properties.count_graphics >= priorities.size ())
|
int present = get_present_queue_index (device.physical_device, device.surface, device.queue_families);
|
||||||
info.graphics_queue_priorities = priorities;
|
if (present >= 0) {
|
||||||
return *this;
|
return get_queue (device.device, present);
|
||||||
}
|
}
|
||||||
DeviceBuilder& DeviceBuilder::set_compute_queue_priorities (std::vector<float> priorities) {
|
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "presentation queue is not available" };
|
||||||
if (info.physical_device.queue_family_properties.count_compute >= priorities.size ())
|
|
||||||
info.compute_queue_priorities = priorities;
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
DeviceBuilder& DeviceBuilder::set_transfer_queue_priorities (std::vector<float> priorities) {
|
detail::Expected<VkQueue, VkResult> get_graphics_queue (Device const& device) {
|
||||||
if (info.physical_device.queue_family_properties.count_transfer >= priorities.size ())
|
int graphics = get_graphics_queue_index (device.physical_device, device.surface, device.queue_families);
|
||||||
info.transfer_queue_priorities = priorities;
|
if (graphics >= 0) {
|
||||||
return *this;
|
return get_queue (device.device, graphics);
|
||||||
}
|
}
|
||||||
DeviceBuilder& DeviceBuilder::set_sparse_queue_priorities (std::vector<float> priorities) {
|
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "requested queue family is not available" };
|
||||||
if (info.physical_device.queue_family_properties.count_sparse >= priorities.size ())
|
}
|
||||||
info.sparse_queue_priorities = priorities;
|
detail::Expected<VkQueue, VkResult> get_compute_queue (Device const& device) {
|
||||||
return *this;
|
int compute = get_distinct_compute_queue_index (device.physical_device, device.surface, device.queue_families);
|
||||||
|
if (compute >= 0) {
|
||||||
|
return get_queue (device.device, compute);
|
||||||
|
}
|
||||||
|
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "requested queue family is not available" };
|
||||||
|
}
|
||||||
|
detail::Expected<VkQueue, VkResult> get_transfer_queue (Device const& device) {
|
||||||
|
int transfer = get_distinct_transfer_queue_index (device.physical_device, device.surface, device.queue_families);
|
||||||
|
if (transfer >= 0) {
|
||||||
|
return get_queue (device.device, transfer);
|
||||||
|
}
|
||||||
|
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "requested queue family is not available" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---- Queue ---- //
|
|
||||||
|
|
||||||
uint32_t get_queue_index_present (Device const& device) {
|
|
||||||
return device.physical_device.queue_family_properties.present;
|
|
||||||
}
|
|
||||||
uint32_t get_queue_index_graphics (Device const& device) {
|
|
||||||
return device.physical_device.queue_family_properties.graphics;
|
|
||||||
}
|
|
||||||
uint32_t get_queue_index_compute (Device const& device) {
|
|
||||||
return device.physical_device.queue_family_properties.compute;
|
|
||||||
}
|
|
||||||
uint32_t get_queue_index_transfer (Device const& device) {
|
|
||||||
return device.physical_device.queue_family_properties.transfer;
|
|
||||||
}
|
|
||||||
uint32_t get_queue_index_sparse (Device const& device) {
|
|
||||||
return device.physical_device.queue_family_properties.sparse;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
VkQueue get_queue (Device const& device, uint32_t family, uint32_t index) {
|
|
||||||
VkQueue queue;
|
|
||||||
vkGetDeviceQueue (device.device, family, index, &queue);
|
|
||||||
return queue;
|
|
||||||
}
|
|
||||||
} // namespace detail
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_present (Device const& device) {
|
|
||||||
return detail::get_queue (device, device.physical_device.queue_family_properties.present, 0);
|
|
||||||
}
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_graphics (Device const& device, uint32_t index) {
|
|
||||||
if (index >= device.physical_device.queue_family_properties.count_graphics)
|
|
||||||
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "requested graphics queue index is out of bounds" };
|
|
||||||
return detail::get_queue (device, device.physical_device.queue_family_properties.graphics, index);
|
|
||||||
}
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_compute (Device const& device, uint32_t index) {
|
|
||||||
if (index >= device.physical_device.queue_family_properties.count_compute)
|
|
||||||
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "requested compute queue index is out of bounds" };
|
|
||||||
return detail::get_queue (device, device.physical_device.queue_family_properties.compute, index);
|
|
||||||
}
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_transfer (Device const& device, uint32_t index) {
|
|
||||||
if (index >= device.physical_device.queue_family_properties.count_transfer)
|
|
||||||
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "requested transfer queue index is out of bounds" };
|
|
||||||
return detail::get_queue (device, device.physical_device.queue_family_properties.transfer, index);
|
|
||||||
}
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_sparse (Device const& device, uint32_t index) {
|
|
||||||
if (index >= device.physical_device.queue_family_properties.count_sparse)
|
|
||||||
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "requested sparse queue index is out of bounds" };
|
|
||||||
return detail::get_queue (device, device.physical_device.queue_family_properties.sparse, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
VkSurfaceFormatKHR find_surface_format (std::vector<VkSurfaceFormatKHR> const& available_formats,
|
VkSurfaceFormatKHR find_surface_format (std::vector<VkSurfaceFormatKHR> const& available_formats,
|
||||||
std::vector<VkSurfaceFormatKHR> const& desired_formats) {
|
std::vector<VkSurfaceFormatKHR> const& desired_formats) {
|
||||||
|
@ -199,33 +199,19 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL default_debug_callback (VkDebugUtilsMessag
|
|||||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||||
void* pUserData);
|
void* pUserData);
|
||||||
|
|
||||||
struct QueueFamilies {
|
|
||||||
int graphics = -1;
|
|
||||||
int present = -1;
|
|
||||||
int transfer = -1;
|
|
||||||
int compute = -1;
|
|
||||||
int sparse = -1;
|
|
||||||
uint32_t count_graphics = 0;
|
|
||||||
uint32_t count_transfer = 0;
|
|
||||||
uint32_t count_compute = 0;
|
|
||||||
uint32_t count_sparse = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
QueueFamilies find_queue_families (VkPhysicalDevice phys_device, VkSurfaceKHR surface);
|
|
||||||
|
|
||||||
// ---- Physical Device ---- //
|
// ---- Physical Device ---- //
|
||||||
|
class PhysicalDeviceSelector;
|
||||||
|
class DeviceBuilder;
|
||||||
|
|
||||||
struct PhysicalDevice {
|
struct PhysicalDevice {
|
||||||
VkPhysicalDevice phys_device = VK_NULL_HANDLE;
|
VkPhysicalDevice phys_device = VK_NULL_HANDLE;
|
||||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
private:
|
||||||
VkPhysicalDeviceFeatures features{};
|
VkPhysicalDeviceFeatures features{};
|
||||||
VkPhysicalDeviceProperties properties{};
|
|
||||||
VkPhysicalDeviceMemoryProperties memory_properties{};
|
|
||||||
|
|
||||||
QueueFamilies queue_family_properties;
|
|
||||||
|
|
||||||
std::vector<std::string> extensions_to_enable;
|
std::vector<std::string> extensions_to_enable;
|
||||||
|
friend class PhysicalDeviceSelector;
|
||||||
|
friend class DeviceBuilder;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PhysicalDeviceSelector {
|
struct PhysicalDeviceSelector {
|
||||||
@ -257,7 +243,6 @@ struct PhysicalDeviceSelector {
|
|||||||
PhysicalDeviceSelector& set_minimum_version (uint32_t major = 1, uint32_t minor = 0);
|
PhysicalDeviceSelector& set_minimum_version (uint32_t major = 1, uint32_t minor = 0);
|
||||||
|
|
||||||
PhysicalDeviceSelector& set_required_features (VkPhysicalDeviceFeatures features);
|
PhysicalDeviceSelector& set_required_features (VkPhysicalDeviceFeatures features);
|
||||||
PhysicalDeviceSelector& set_desired_features (VkPhysicalDeviceFeatures features);
|
|
||||||
|
|
||||||
PhysicalDeviceSelector& select_first_device_unconditionally (bool unconditionally = true);
|
PhysicalDeviceSelector& select_first_device_unconditionally (bool unconditionally = true);
|
||||||
|
|
||||||
@ -284,7 +269,6 @@ struct PhysicalDeviceSelector {
|
|||||||
uint32_t desired_version = VK_MAKE_VERSION (1, 0, 0);
|
uint32_t desired_version = VK_MAKE_VERSION (1, 0, 0);
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures required_features{};
|
VkPhysicalDeviceFeatures required_features{};
|
||||||
VkPhysicalDeviceFeatures desired_features{};
|
|
||||||
|
|
||||||
bool use_first_gpu_unconditionally = false;
|
bool use_first_gpu_unconditionally = false;
|
||||||
} criteria;
|
} criteria;
|
||||||
@ -294,12 +278,17 @@ struct PhysicalDeviceSelector {
|
|||||||
Suitable is_device_suitable (VkPhysicalDevice phys_device);
|
Suitable is_device_suitable (VkPhysicalDevice phys_device);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ---- Queue Selection ---- //
|
||||||
|
|
||||||
|
enum class QueueType : uint8_t { primary, compute, transfer };
|
||||||
|
|
||||||
// ---- Device ---- //
|
// ---- Device ---- //
|
||||||
|
|
||||||
struct Device {
|
struct Device {
|
||||||
VkDevice device = VK_NULL_HANDLE;
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
PhysicalDevice physical_device;
|
PhysicalDevice physical_device;
|
||||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||||
|
std::vector<VkQueueFamilyProperties> queue_families;
|
||||||
};
|
};
|
||||||
|
|
||||||
void destroy_device (Device device);
|
void destroy_device (Device device);
|
||||||
@ -311,43 +300,24 @@ class DeviceBuilder {
|
|||||||
|
|
||||||
template <typename T> DeviceBuilder& add_pNext (T* structure);
|
template <typename T> DeviceBuilder& add_pNext (T* structure);
|
||||||
|
|
||||||
DeviceBuilder& use_multiple_queues_per_family (bool multi_queue = true);
|
|
||||||
|
|
||||||
DeviceBuilder& set_graphics_queue_priorities (std::vector<float> priorities);
|
|
||||||
DeviceBuilder& set_compute_queue_priorities (std::vector<float> priorities);
|
|
||||||
DeviceBuilder& set_transfer_queue_priorities (std::vector<float> priorities);
|
|
||||||
DeviceBuilder& set_sparse_queue_priorities (std::vector<float> priorities);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct DeviceInfo {
|
struct DeviceInfo {
|
||||||
VkDeviceCreateFlags flags;
|
VkDeviceCreateFlags flags;
|
||||||
std::vector<VkBaseOutStructure*> pNext_chain;
|
std::vector<VkBaseOutStructure*> pNext_chain;
|
||||||
PhysicalDevice physical_device;
|
PhysicalDevice physical_device;
|
||||||
std::vector<std::string> extensions;
|
std::vector<std::string> extensions;
|
||||||
|
|
||||||
bool use_multiple_queues_per_family = false;
|
|
||||||
std::vector<float> graphics_queue_priorities;
|
|
||||||
std::vector<float> compute_queue_priorities;
|
|
||||||
std::vector<float> transfer_queue_priorities;
|
|
||||||
std::vector<float> sparse_queue_priorities;
|
|
||||||
|
|
||||||
} info;
|
} info;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---- Queue ---- //
|
// ---- Getting Queues ---- //
|
||||||
|
|
||||||
uint32_t get_queue_index_present (Device const& device);
|
detail::Expected<VkQueue, VkResult> get_present_queue (Device const& device);
|
||||||
uint32_t get_queue_index_graphics (Device const& device);
|
detail::Expected<VkQueue, VkResult> get_graphics_queue (Device const& device);
|
||||||
uint32_t get_queue_index_compute (Device const& device);
|
detail::Expected<VkQueue, VkResult> get_compute_queue (Device const& device);
|
||||||
uint32_t get_queue_index_transfer (Device const& device);
|
detail::Expected<VkQueue, VkResult> get_transfer_queue (Device const& device);
|
||||||
uint32_t get_queue_index_sparse (Device const& device);
|
|
||||||
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_present (Device const& device);
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_graphics (Device const& device, uint32_t index = 0);
|
// ---- Swapchain ---- //
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_compute (Device const& device, uint32_t index = 0);
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_transfer (Device const& device, uint32_t index = 0);
|
|
||||||
detail::Expected<VkQueue, VkResult> get_queue_sparse (Device const& device, uint32_t index = 0);
|
|
||||||
|
|
||||||
struct Swapchain {
|
struct Swapchain {
|
||||||
VkDevice device = VK_NULL_HANDLE;
|
VkDevice device = VK_NULL_HANDLE;
|
||||||
@ -358,6 +328,7 @@ struct Swapchain {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void destroy_swapchain (Swapchain const& swapchain);
|
void destroy_swapchain (Swapchain const& swapchain);
|
||||||
|
|
||||||
detail::Expected<std::vector<VkImage>, VkResult> get_swapchain_images (Swapchain const& swapchain);
|
detail::Expected<std::vector<VkImage>, VkResult> get_swapchain_images (Swapchain const& swapchain);
|
||||||
detail::Expected<std::vector<VkImageView>, VkResult> get_swapchain_image_views (
|
detail::Expected<std::vector<VkImageView>, VkResult> get_swapchain_image_views (
|
||||||
Swapchain const& swapchain, std::vector<VkImage> const& images);
|
Swapchain const& swapchain, std::vector<VkImage> const& images);
|
||||||
@ -394,6 +365,8 @@ class SwapchainBuilder {
|
|||||||
uint32_t desired_width = 256;
|
uint32_t desired_width = 256;
|
||||||
uint32_t desired_height = 256;
|
uint32_t desired_height = 256;
|
||||||
std::vector<VkBaseOutStructure*> pNext_elements;
|
std::vector<VkBaseOutStructure*> pNext_elements;
|
||||||
|
uint32_t graphics_queue_index = 0;
|
||||||
|
uint32_t present_queue_index = 0;
|
||||||
} info;
|
} info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user