Qt GUIにおけるQVulkanWindow::graphicsQueueFamilyIndex()の詳細解説


QVulkanWindow::graphicsQueueFamilyIndex()は、Vulkan APIにおけるグラフィックスキューファミリーのインデックスを取得する関数です。グラフィックスキューファミリーは、Vulkanレンダリング操作を実行するために使用されるキューのグループです。

詳細

Vulkan APIでは、様々な種類のキューが定義されています。それぞれのキューは、特定のタスクを実行するために設計されています。グラフィックスキューファミリーは、レンダリングコマンドの送信や同期などのレンダリング操作を実行するために使用されます。

QVulkanWindow::graphicsQueueFamilyIndex()は、現在のVulkanレンダリングコンテキストに関連付けられているグラフィックスキューファミリーのインデックスを返します。このインデックスは、vkGetPhysicalDeviceQueueFamilies()関数を使用して取得されたキューファミリーリストのインデックスに対応します。

以下のコードは、QVulkanWindow::graphicsQueueFamilyIndex()を使用して、グラフィックスキューファミリーのインデックスを取得し、そのインデックスを使用してキューを作成する例です。

#include <QtVulkan>

int main() {
  QVulkanWindow window;
  if (!window.create()) {
    return -1;
  }

  uint32_t graphicsQueueFamilyIndex = window.graphicsQueueFamilyIndex();

  VkQueue graphicsQueue;
  vkGetDeviceQueue(window.device(), graphicsQueueFamilyIndex, 0, &graphicsQueue);

  // グラフィックスキューを使用してレンダリング操作を実行します。

  return 0;
}
  • 複数のグラフィックスキューファミリーが存在する場合は、アプリケーションは適切なキューファミリーを選択する必要があります。
  • グラフィックスキューファミリーのインデックスは、Vulkanレンダリングコンテキストごとに異なる場合があります。
  • QVulkanWindow::graphicsQueueFamilyIndex()は、Vulkanレンダリングコンテキストが作成された後にのみ呼び出すことができます。


QVulkanWindow::graphicsQueueFamilyIndex()を使用してキューを作成する例

#include <QtVulkan>

int main() {
  QVulkanWindow window;
  if (!window.create()) {
    return -1;
  }

  uint32_t graphicsQueueFamilyIndex = window.graphicsQueueFamilyIndex();

  VkQueue graphicsQueue;
  vkGetDeviceQueue(window.device(), graphicsQueueFamilyIndex, 0, &graphicsQueue);

  // グラフィックスキューを使用してレンダリング操作を実行します。

  return 0;
}

この例では、QVulkanWindow::graphicsQueueFamilyIndex()を使用して、グラフィックスキューファミリーのインデックスを取得しています。次に、このインデックスを使用して、vkGetDeviceQueue()関数を使用してキューを作成しています。

#include <QtVulkan>

int main() {
  QVulkanWindow window;
  if (!window.create()) {
    return -1;
  }

  uint32_t queueFamilyCount;
  vkGetPhysicalDeviceQueueFamilies(window.physicalDevice(), &queueFamilyCount, nullptr);

  std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);
  vkGetPhysicalDeviceQueueFamilies(window.physicalDevice(), &queueFamilyCount, queueFamilyProperties.data());

  uint32_t graphicsQueueFamilyIndex = -1;
  uint32_t presentQueueFamilyIndex = -1;

  for (uint32_t i = 0; i < queueFamilyCount; ++i) {
    if (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
      graphicsQueueFamilyIndex = i;
    }

    if (queueFamilyProperties[i].queueFlags & VK_QUEUE_PRESENT_BIT) {
      presentQueueFamilyIndex = i;
    }
  }

  if (graphicsQueueFamilyIndex == -1 || presentQueueFamilyIndex == -1) {
    return -1;
  }

  VkQueue graphicsQueue;
  vkGetDeviceQueue(window.device(), graphicsQueueFamilyIndex, 0, &graphicsQueue);

  VkQueue presentQueue;
  vkGetDeviceQueue(window.device(), presentQueueFamilyIndex, 0, &presentQueue);

  // グラフィックスキューとプレゼンテーションキューを使用してレンダリング操作を実行します。

  return 0;
}


代替方法

  1. vkGetPhysicalDeviceQueueFamilies()関数を使用する

vkGetPhysicalDeviceQueueFamilies()関数は、すべてのキューファミリーとその機能を取得します。この関数を使用して、グラフィックスキューファミリーを手動で特定することができます。

#include <vulkan/vulkan.h>

uint32_t getGraphicsQueueFamilyIndex(VkPhysicalDevice physicalDevice) {
  uint32_t queueFamilyCount;
  vkGetPhysicalDeviceQueueFamilies(physicalDevice, &queueFamilyCount, nullptr);

  std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);
  vkGetPhysicalDeviceQueueFamilies(physicalDevice, &queueFamilyCount, queueFamilyProperties.data());

  for (uint32_t i = 0; i < queueFamilyCount; ++i) {
    if (queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
      return i;
    }
  }

  return -1;
}

QVulkanWindow::createSurface()関数を使用する

QVulkanWindow::createSurface()関数は、Vulkanレンダリングコンテキストに関連付けられているプレゼンテーションキューファミリーのインデックスを返します。このインデックスは、グラフィックスキューファミリーと一致していることが保証されています。

#include <QtVulkan>

uint32_t getGraphicsQueueFamilyIndex(QVulkanWindow& window) {
  VkSurfaceKHR surface;
  if (!window.createSurface(&surface)) {
    return -1;
  }

  VkPhysicalDevice physicalDevice = window.physicalDevice();
  VkSurfaceCapabilitiesKHR surfaceCapabilities;
  vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &surfaceCapabilities);

  uint32_t queueFamilyCount;
  vkGetPhysicalDeviceQueueFamilies(physicalDevice, &queueFamilyCount, nullptr);

  std::vector<VkQueueFamilyProperties> queueFamilyProperties(queueFamilyCount);
  vkGetPhysicalDeviceQueueFamilies(physicalDevice, &queueFamilyCount, queueFamilyProperties.data());

  for (uint32_t i = 0; i < queueFamilyCount; ++i) {
    VkBool32 supported = VK_FALSE;
    vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, &supported);

    if (supported) {
      return i;
    }
  }

  return -1;
}

サードパーティのライブラリを使用する

Vulkan APIのラッパーライブラリの中には、QVulkanWindow::graphicsQueueFamilyIndex()の代替機能を提供するものがあります。これらのライブラリは、より使いやすく、コードを簡潔にすることができます。