Продолжаем разбирать спецификацию, в прошлый раз мы разобрались как получить списк доступных физических устройств и их свойств. Каждое физическое устройство может иметь одно или несколько семейств очередей, в этой статье мы научимся получать список таких семейств и определять их свойства.
Для физического устройства мы можем запросить свойства доступных семейств очередей через команду:
void vkGetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice,
uint32_t * pQueueFamilyPropertyCount,
VkQueueFamilyProperties * pQueueFamilyProperties);
• physicalDevice - хэндл физического устройства, у которого будут запрашиваться свойства.
• pQueueFamilyPropertyCount - указатель на переменную куда вернется количество имеющихся семейств очередей.
• pQueueFamilyProperties - указатель на массив структур типа VkQueueFamilyProperties. Если NULL - функция вернет количество семейств очередей в pQueueFamilyPropertyCount.
Структура VkQueueFamilyProperties опредлена как:
typedef struct VkQueueFamilyProperties {
VkQueueFlags queueFlags;
uint32_t queueCount;
uint32_t timestampValidBits;
VkExtent3D minImageTransferGranularity;
} VkQueueFamilyProperties;
• queueFlags - содержит флаги, отображающие возможности очередей в семействе.
• queueCount - количество очередей в семействе.
• timestampValidBits - количество значащих бит в штампе времени, записанном через
vkCmdWriteTimestamp. Допустимое значение - от 36 до 64 бит, или 0, если таймстэмпы не поддерживаются. Биты вне данного диапазона гарантированно будут нулями.
• minImageTransferGranularity - минимальный блок передаваемого изображения, поддерживаемый очередью.
Значение битов в queueFlags:
typedef enum VkQueueFlagBits {
VK_QUEUE_GRAPHICS_BIT = 0x00000001,
VK_QUEUE_COMPUTE_BIT = 0x00000002,
VK_QUEUE_TRANSFER_BIT = 0x00000004,
VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
} VkQueueFlagBits;
• VK_QUEUE_GRAPHICS_BIT - семейство очередей поддерживает графические операции.
• VK_QUEUE_COMPUTE_BIT - семейство очередей поддерживает вычислительные операции.
• VK_QUEUE_TRANSFER_BIT - семейство очередей поддерживает операции передачи данных.
• VK_QUEUE_SPARSE_BINDING_BIT - семейство очередей поддерживает разряженные операции работы с памятью (sparse memory management operations).
Если реализация предоставляет семейство, поддерживающее графические операции, то как минимум одно семейство на одном из физических устройств должно поддерживать как графические так и вычислительные операции.
Значение, возвращаемое в minImageTransferGranularity содержит количество текстелей или количество блоков сжатого изображения.
Возможные значения для minImageTransferGranularity:
• (0,0,0) - в соответствующей очереди допускается передача только целого мип-уровня за раз. В этом случае налагаются следующие ограничения на смещения и размеры параметров передаваемого изображения:
– Поля x, y и z параметра VkOffset3D всегда должны быть равны 0.
– Поля width, height и depth параметра VkExtent3D должны всегда совпадать с width, height и depth соовтетствующего лода изображаения.
• (Ax,Ay,Az), где Ax, Ay и Az это целые степени двойки. В этом случае на предачу изображения налагаются следующие ограничения:
– x, y и z параметра VkOffset3D должны быть целими кратными Ax, Ay, и Az.
– width, height, depth параметры VkExtent3D должны быть кратными Ax, Ay, и Az соответственно, или (x+width), (y+height) и (z+depth) должны быть равны соответствующим размерам лода изображения.
– Если формат изображения соответствует одному из блоков сжатого изображения, тогда для указанных выше расчетов размер данных должен быть кратен размеру блока.
Очереди, поддерживающие графические и/или вычислительные операции должны репортить (1,1,1) в minImageTransferGranularity, что означает что нет никаких дополнительных ограничений на размеры блоков при передаче изображения. Для других очередей, поддерживающих передачу изображений, существует требование только к передаче мип-уровня целиком, таким образом, значение minImageTransferGranularity для данного семейства очередей должно быть (0,0,0).
====================================================================
Пример вывода результата (свойств семейств очередей) для разного типа устройств:
Found 2 Physical devices, Device Properties:
0: apiVersion: 0.0.1; driverVersion: 0.0.1; vendorId: 4098; deviceId: 4879; deviceType: 1; deviceName: AMD Radeon(TM) R7 Graphics
Device AMD Radeon(TM) R7 Graphics has queues families: 3
0: queueFlags: GRAPHICS|COMPUTE||SPARSE_BINDING; queueCount: 1; timestampValidBits: 63; minImageTransferGranularity(w,h,d): (0,0,0)
1: queueFlags: |COMPUTE||SPARSE_BINDING; queueCount: 1; timestampValidBits: 63; minImageTransferGranularity(w,h,d): (3452816845,3452816845,3452816845)
2: queueFlags: ||TRANSFER|SPARSE_BINDING; queueCount: 2; timestampValidBits: 63; minImageTransferGranularity(w,h,d): (3452816845,3452816845,3452816845)
1: apiVersion: 1.0.3; driverVersion: 1.0.3; vendorId: 4318; deviceId: 4992; deviceType: 2; deviceName: GTX 750 Ti
Device GTX 750 Ti has queues families: 1
0: queueFlags: GRAPHICS|COMPUTE|TRANSFER|SPARSE_BINDING; queueCount: 16; timestampValidBits: 64; minImageTransferGranularity(w,h,d): (1,1,1)
Как видно из лога, набор и свойства очередей существенно отличаются между вендорами, и если NVidia “прощает” неудачный выбор семейства очередей, то с AMD нужно быть очень внимательными. Так же стоит отметить что возвращаемый результат для AMD не соответствует спецификации, где сказано, дословно, что:
Queues supporting graphics and/or compute operations must report (1,1,1) in minImageTransferGranularity, meaning that there are no additional restrictions on the granularity of image transfer operations for these queues.Ну или по-русски - если очередь поддерживает графические и/или вычислительные операции, то minImageTransferGranularity должнобыть равно (1,1,1), однако AMD как обычно не следует спецификации, возможно потому что версия драйвера и API всего 0.0.1.
Здесь вы можете найти Исходный код примера получения списка устройств, доступных у них очередей и их свойств.
Комментариев нет:
Отправить комментарий