mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-26 08:44:36 +00:00
Use uint32_t in Queues everywhere, add QUEUE_INDEX_MAX_VALUE as sentinel
This commit removes the many casts from int to uint and back, as -1 was used as a sentinel value. Because thats confusing and leads to many casts everywhere it was decided to add a sentinel value and compare everything to that to determine if a queue index is valid or not.
This commit is contained in:
parent
daf244d180
commit
4120362762
@ -911,79 +911,80 @@ bool supports_features (VkPhysicalDeviceFeatures supported, VkPhysicalDeviceFeat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// finds the first queue which supports graphics operations. returns -1 if none is found
|
// finds the first queue which supports graphics operations. returns QUEUE_INDEX_MAX_VALUE if none is found
|
||||||
int get_graphics_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
uint32_t get_graphics_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
for (size_t i = 0; i < families.size (); i++) {
|
for (uint32_t i = 0; i < static_cast<uint32_t> (families.size ()); i++) {
|
||||||
if (families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) return static_cast<int> (i);
|
if (families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
// finds a compute queue which is separate from the graphics queue and tries to find one without
|
// finds a compute queue which is separate from the graphics queue and tries to find one without
|
||||||
// transfer support returns -1 if none is found
|
// transfer support returns QUEUE_INDEX_MAX_VALUE if none is found
|
||||||
int get_separate_compute_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
uint32_t get_separate_compute_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
int compute = -1;
|
uint32_t compute = QUEUE_INDEX_MAX_VALUE;
|
||||||
for (size_t i = 0; i < families.size (); i++) {
|
for (uint32_t i = 0; i < static_cast<uint32_t> (families.size ()); i++) {
|
||||||
if ((families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
|
if ((families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
|
||||||
((families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
|
((families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
|
||||||
if ((families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0) {
|
if ((families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0) {
|
||||||
return static_cast<int> (i);
|
return i;
|
||||||
} else {
|
} else {
|
||||||
compute = static_cast<int> (i);
|
compute = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return compute;
|
return compute;
|
||||||
}
|
}
|
||||||
// finds a transfer queue which is separate from the graphics queue and tries to find one without
|
// finds a transfer queue which is separate from the graphics queue and tries to find one without
|
||||||
// compute support returns -1 if none is found
|
// compute support returns QUEUE_INDEX_MAX_VALUE if none is found
|
||||||
int get_separate_transfer_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
uint32_t get_separate_transfer_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
int transfer = -1;
|
uint32_t transfer = QUEUE_INDEX_MAX_VALUE;
|
||||||
for (size_t i = 0; i < families.size (); i++) {
|
for (uint32_t i = 0; i < static_cast<uint32_t> (families.size ()); i++) {
|
||||||
if ((families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) &&
|
if ((families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) &&
|
||||||
((families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
|
((families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0)) {
|
||||||
if ((families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) == 0) {
|
if ((families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) == 0) {
|
||||||
return static_cast<int> (i);
|
return i;
|
||||||
} else {
|
} else {
|
||||||
transfer = static_cast<int> (i);
|
transfer = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return transfer;
|
return transfer;
|
||||||
}
|
}
|
||||||
// finds the first queue which supports only compute (not graphics or transfer). returns -1 if none is found
|
// finds the first queue which supports only compute (not graphics or transfer). returns QUEUE_INDEX_MAX_VALUE if none is found
|
||||||
int get_dedicated_compute_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
uint32_t get_dedicated_compute_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
for (size_t i = 0; i < families.size (); i++) {
|
for (uint32_t i = 0; i < static_cast<uint32_t> (families.size ()); i++) {
|
||||||
if ((families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
|
if ((families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) &&
|
||||||
(families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0 &&
|
(families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0 &&
|
||||||
(families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0)
|
(families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0)
|
||||||
return static_cast<int> (i);
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
// finds the first queue which supports only transfer (not graphics or compute). returns -1 if none is found
|
// finds the first queue which supports only transfer (not graphics or compute). returns QUEUE_INDEX_MAX_VALUE if none is found
|
||||||
int get_dedicated_transfer_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
uint32_t get_dedicated_transfer_queue_index (std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
for (size_t i = 0; i < families.size (); i++) {
|
for (uint32_t i = 0; i < static_cast<uint32_t> (families.size ()); i++) {
|
||||||
if ((families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) &&
|
if ((families[i].queueFlags & VK_QUEUE_TRANSFER_BIT) &&
|
||||||
(families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0 &&
|
(families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) == 0 &&
|
||||||
(families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) == 0)
|
(families[i].queueFlags & VK_QUEUE_COMPUTE_BIT) == 0)
|
||||||
return static_cast<int> (i);
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
// finds the first queue which supports presenting. returns -1 if none is found
|
// finds the first queue which supports presenting. returns QUEUE_INDEX_MAX_VALUE if none is found
|
||||||
int get_present_queue_index (VkPhysicalDevice const phys_device,
|
uint32_t get_present_queue_index (VkPhysicalDevice const phys_device,
|
||||||
VkSurfaceKHR const surface,
|
VkSurfaceKHR const surface,
|
||||||
std::vector<VkQueueFamilyProperties> const& families) {
|
std::vector<VkQueueFamilyProperties> const& families) {
|
||||||
for (size_t i = 0; i < families.size (); i++) {
|
for (uint32_t i = 0; i < static_cast<uint32_t> (families.size ()); i++) {
|
||||||
VkBool32 presentSupport = false;
|
VkBool32 presentSupport = false;
|
||||||
if (surface != VK_NULL_HANDLE) {
|
if (surface != VK_NULL_HANDLE) {
|
||||||
VkResult res = detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfaceSupportKHR (
|
VkResult res = detail::vulkan_functions ().fp_vkGetPhysicalDeviceSurfaceSupportKHR (
|
||||||
phys_device, static_cast<uint32_t> (i), surface, &presentSupport);
|
phys_device, i, surface, &presentSupport);
|
||||||
if (res != VK_SUCCESS) return -1; // TODO: determine if this should fail another way
|
if (res != VK_SUCCESS)
|
||||||
|
return QUEUE_INDEX_MAX_VALUE; // TODO: determine if this should fail another way
|
||||||
}
|
}
|
||||||
if (presentSupport == VK_TRUE) return static_cast<int> (i);
|
if (presentSupport == VK_TRUE) return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
@ -1008,13 +1009,18 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (Phy
|
|||||||
if (criteria.required_version > pd.device_properties.apiVersion) return Suitable::no;
|
if (criteria.required_version > pd.device_properties.apiVersion) return Suitable::no;
|
||||||
if (criteria.desired_version > pd.device_properties.apiVersion) suitable = Suitable::partial;
|
if (criteria.desired_version > pd.device_properties.apiVersion) suitable = Suitable::partial;
|
||||||
|
|
||||||
bool dedicated_compute = detail::get_dedicated_compute_queue_index (pd.queue_families) >= 0;
|
bool dedicated_compute =
|
||||||
bool dedicated_transfer = detail::get_dedicated_transfer_queue_index (pd.queue_families) >= 0;
|
detail::get_dedicated_compute_queue_index (pd.queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
bool separate_compute = detail::get_separate_compute_queue_index (pd.queue_families) >= 0;
|
bool dedicated_transfer =
|
||||||
bool separate_transfer = detail::get_separate_transfer_queue_index (pd.queue_families) >= 0;
|
detail::get_dedicated_transfer_queue_index (pd.queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
|
bool separate_compute =
|
||||||
|
detail::get_separate_compute_queue_index (pd.queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
|
bool separate_transfer =
|
||||||
|
detail::get_separate_transfer_queue_index (pd.queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
|
|
||||||
bool present_queue =
|
bool present_queue =
|
||||||
detail::get_present_queue_index (pd.phys_device, system_info.surface, pd.queue_families) >= 0;
|
detail::get_present_queue_index (pd.phys_device, system_info.surface, pd.queue_families) !=
|
||||||
|
detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
|
|
||||||
if (criteria.require_dedicated_compute_queue && !dedicated_compute) return Suitable::no;
|
if (criteria.require_dedicated_compute_queue && !dedicated_compute) return Suitable::no;
|
||||||
if (criteria.require_dedicated_transfer_queue && !dedicated_transfer) return Suitable::no;
|
if (criteria.require_dedicated_transfer_queue && !dedicated_transfer) return Suitable::no;
|
||||||
@ -1237,16 +1243,16 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditiona
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicalDevice::has_dedicated_compute_queue () const {
|
bool PhysicalDevice::has_dedicated_compute_queue () const {
|
||||||
return detail::get_dedicated_compute_queue_index (queue_families) >= 0;
|
return detail::get_dedicated_compute_queue_index (queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
bool PhysicalDevice::has_separate_compute_queue () const {
|
bool PhysicalDevice::has_separate_compute_queue () const {
|
||||||
return detail::get_separate_compute_queue_index (queue_families) >= 0;
|
return detail::get_separate_compute_queue_index (queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
bool PhysicalDevice::has_dedicated_transfer_queue () const {
|
bool PhysicalDevice::has_dedicated_transfer_queue () const {
|
||||||
return detail::get_dedicated_transfer_queue_index (queue_families) >= 0;
|
return detail::get_dedicated_transfer_queue_index (queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
bool PhysicalDevice::has_separate_transfer_queue () const {
|
bool PhysicalDevice::has_separate_transfer_queue () const {
|
||||||
return detail::get_separate_transfer_queue_index (queue_families) >= 0;
|
return detail::get_separate_transfer_queue_index (queue_families) != detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
}
|
}
|
||||||
std::vector<VkQueueFamilyProperties> PhysicalDevice::get_queue_families () const {
|
std::vector<VkQueueFamilyProperties> PhysicalDevice::get_queue_families () const {
|
||||||
return queue_families;
|
return queue_families;
|
||||||
@ -1255,44 +1261,50 @@ std::vector<VkQueueFamilyProperties> PhysicalDevice::get_queue_families () const
|
|||||||
// ---- Queues ---- //
|
// ---- Queues ---- //
|
||||||
|
|
||||||
detail::Result<uint32_t> Device::get_queue_index (QueueType type) const {
|
detail::Result<uint32_t> Device::get_queue_index (QueueType type) const {
|
||||||
int index = -1;
|
uint32_t index = detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QueueType::present:
|
case QueueType::present:
|
||||||
index = detail::get_present_queue_index (physical_device.physical_device, surface, queue_families);
|
index = detail::get_present_queue_index (physical_device.physical_device, surface, queue_families);
|
||||||
if (index < 0) return detail::Result<uint32_t>{ QueueError::present_unavailable };
|
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
|
return detail::Result<uint32_t>{ QueueError::present_unavailable };
|
||||||
break;
|
break;
|
||||||
case QueueType::graphics:
|
case QueueType::graphics:
|
||||||
index = detail::get_graphics_queue_index (queue_families);
|
index = detail::get_graphics_queue_index (queue_families);
|
||||||
if (index < 0) return detail::Result<uint32_t>{ QueueError::graphics_unavailable };
|
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
|
return detail::Result<uint32_t>{ QueueError::graphics_unavailable };
|
||||||
break;
|
break;
|
||||||
case QueueType::compute:
|
case QueueType::compute:
|
||||||
index = detail::get_separate_compute_queue_index (queue_families);
|
index = detail::get_separate_compute_queue_index (queue_families);
|
||||||
if (index < 0) return detail::Result<uint32_t>{ QueueError::compute_unavailable };
|
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
|
return detail::Result<uint32_t>{ QueueError::compute_unavailable };
|
||||||
break;
|
break;
|
||||||
case QueueType::transfer:
|
case QueueType::transfer:
|
||||||
index = detail::get_separate_transfer_queue_index (queue_families);
|
index = detail::get_separate_transfer_queue_index (queue_families);
|
||||||
if (index < 0) return detail::Result<uint32_t>{ QueueError::transfer_unavailable };
|
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
|
return detail::Result<uint32_t>{ QueueError::transfer_unavailable };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return detail::Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
return detail::Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
||||||
}
|
}
|
||||||
return static_cast<uint32_t> (index);
|
return index;
|
||||||
}
|
}
|
||||||
detail::Result<uint32_t> Device::get_dedicated_queue_index (QueueType type) const {
|
detail::Result<uint32_t> Device::get_dedicated_queue_index (QueueType type) const {
|
||||||
int index = -1;
|
uint32_t index = detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QueueType::compute:
|
case QueueType::compute:
|
||||||
index = detail::get_dedicated_compute_queue_index (queue_families);
|
index = detail::get_dedicated_compute_queue_index (queue_families);
|
||||||
if (index < 0) return detail::Result<uint32_t>{ QueueError::compute_unavailable };
|
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
|
return detail::Result<uint32_t>{ QueueError::compute_unavailable };
|
||||||
break;
|
break;
|
||||||
case QueueType::transfer:
|
case QueueType::transfer:
|
||||||
index = detail::get_dedicated_transfer_queue_index (queue_families);
|
index = detail::get_dedicated_transfer_queue_index (queue_families);
|
||||||
if (index < 0) return detail::Result<uint32_t>{ QueueError::transfer_unavailable };
|
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
|
return detail::Result<uint32_t>{ QueueError::transfer_unavailable };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return detail::Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
return detail::Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
||||||
}
|
}
|
||||||
return static_cast<uint32_t> (index);
|
return index;
|
||||||
}
|
}
|
||||||
namespace detail {
|
namespace detail {
|
||||||
VkQueue get_queue (VkDevice device, uint32_t family) {
|
VkQueue get_queue (VkDevice device, uint32_t family) {
|
||||||
@ -1548,22 +1560,21 @@ SwapchainBuilder::SwapchainBuilder (Device const& device, VkSurfaceKHR const sur
|
|||||||
SwapchainBuilder::SwapchainBuilder (VkPhysicalDevice const physical_device,
|
SwapchainBuilder::SwapchainBuilder (VkPhysicalDevice const physical_device,
|
||||||
VkDevice const device,
|
VkDevice const device,
|
||||||
VkSurfaceKHR const surface,
|
VkSurfaceKHR const surface,
|
||||||
int32_t graphics_queue_index,
|
uint32_t graphics_queue_index,
|
||||||
int32_t present_queue_index) {
|
uint32_t present_queue_index) {
|
||||||
info.physical_device = physical_device;
|
info.physical_device = physical_device;
|
||||||
info.device = device;
|
info.device = device;
|
||||||
info.surface = surface;
|
info.surface = surface;
|
||||||
info.graphics_queue_index = static_cast<uint32_t> (graphics_queue_index);
|
info.graphics_queue_index = graphics_queue_index;
|
||||||
info.present_queue_index = static_cast<uint32_t> (present_queue_index);
|
info.present_queue_index = present_queue_index;
|
||||||
if (graphics_queue_index < 0 || present_queue_index < 0) {
|
if (graphics_queue_index == detail::QUEUE_INDEX_MAX_VALUE || present_queue_index == detail::QUEUE_INDEX_MAX_VALUE) {
|
||||||
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
|
auto queue_families = detail::get_vector_noerror<VkQueueFamilyProperties> (
|
||||||
detail::vulkan_functions ().fp_vkGetPhysicalDeviceQueueFamilyProperties, physical_device);
|
detail::vulkan_functions ().fp_vkGetPhysicalDeviceQueueFamilyProperties, physical_device);
|
||||||
if (graphics_queue_index < 0)
|
if (graphics_queue_index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
info.graphics_queue_index =
|
info.graphics_queue_index = detail::get_graphics_queue_index (queue_families);
|
||||||
static_cast<uint32_t> (detail::get_graphics_queue_index (queue_families));
|
if (present_queue_index == detail::QUEUE_INDEX_MAX_VALUE)
|
||||||
if (present_queue_index < 0)
|
info.present_queue_index =
|
||||||
info.present_queue_index = static_cast<uint32_t> (
|
detail::get_present_queue_index (physical_device, surface, queue_families);
|
||||||
detail::get_present_queue_index (physical_device, surface, queue_families));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
detail::Result<Swapchain> SwapchainBuilder::build () const {
|
detail::Result<Swapchain> SwapchainBuilder::build () const {
|
||||||
|
@ -470,6 +470,11 @@ class PhysicalDeviceSelector {
|
|||||||
// ---- Queue ---- //
|
// ---- Queue ---- //
|
||||||
enum class QueueType { present, graphics, compute, transfer };
|
enum class QueueType { present, graphics, compute, transfer };
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
// Sentinel value, used in implementation only
|
||||||
|
const int QUEUE_INDEX_MAX_VALUE = 65536;
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Device ---- //
|
// ---- Device ---- //
|
||||||
|
|
||||||
struct Device {
|
struct Device {
|
||||||
@ -561,8 +566,8 @@ class SwapchainBuilder {
|
|||||||
explicit SwapchainBuilder (VkPhysicalDevice const physical_device,
|
explicit SwapchainBuilder (VkPhysicalDevice const physical_device,
|
||||||
VkDevice const device,
|
VkDevice const device,
|
||||||
VkSurfaceKHR const surface,
|
VkSurfaceKHR const surface,
|
||||||
int32_t graphics_queue_index = -1,
|
uint32_t graphics_queue_index = detail::QUEUE_INDEX_MAX_VALUE,
|
||||||
int32_t present_queue_index = -1);
|
uint32_t present_queue_index = detail::QUEUE_INDEX_MAX_VALUE);
|
||||||
|
|
||||||
detail::Result<Swapchain> build () const;
|
detail::Result<Swapchain> build () const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user