Vulkan Buffer WorkGroupID не возвращает фактическое значение при большом количестве элементов
Создание буфера с pow(2, 24)
и local_size_x = 64
для разметки входной квалификатор вернется WorkGroupID = 262143
что все в порядке из-за pow(2,24) / 64 - 1
, это ноль индексируется.
Однако, если мы увеличим глобальное измерение / нет элементов / размер проблемы до pow(2, 25)
скажем WorkGroupID
будет возвращать значения без причины, они не соответствуют математике.
Вот некоторые ограничения, которые получили устройства, которые я считаю важными:
maxStorageBufferRange: uint32_t = 4294967295
maxComputeSharedMemorySize: uint32_t = 32768
maxComputeWorkGroupCount: uint32_t[3] = 00000202898A8EC4
maxComputeWorkGroupCount[0]: uint32_t = 65535
maxComputeWorkGroupCount[1]: uint32_t = 65535
maxComputeWorkGroupCount[2]: uint32_t = 65535
maxComputeWorkGroupInvocations: uint32_t = 1024
maxComputeWorkGroupSize: uint32_t[3] = 00000202898A8ED4
maxComputeWorkGroupSize[0]: uint32_t = 1024
maxComputeWorkGroupSize[1]: uint32_t = 1024
maxComputeWorkGroupSize[2]: uint32_t = 1024
Я не перестаю выделять больше элементов, которые поддерживает устройство. Так что через 2 дня + 16 часов я так и не понял, что происходит...
WorkGroupSize
, WorkGroupID
, LocalInvocationID
а также GlobalInvocationID
представляет ту же проблему, когда я достигаю нет. элементов. Неудивительно, что GlobalInvocationID
представляет ту же проблему из-за того, как она рассчитывается...
#version 450
// Size of the Local Work-group is defined trough input layout qualifier
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
layout(set = 0, binding = 0) buffer deviceBuffer
{
uint x[];
};
void main() {
uint i = gl_GlobalInvocationID.x;
//uint i = gl_WorkGroupSize.x * gl_WorkGroupID.x * gl_LocalInvocationID.x;
//x[i] += x[i];
// Total No. of Work Items (threads) in Global Dimension
//x[i] = gl_NumWorkGroups.x;
// Size of Work Dimension specified in Input Layout Qualifier
//x[i] = gl_WorkGroupSize.x;
// Is given by Global Dimension / Work Group Size
x[i] = gl_WorkGroupID.x;
//x[i] = gl_LocalInvocationID.x;
}
1 ответ
maxComputeWorkGroupCount[0]: uint32_t = 65535 maxComputeWorkGroupCount[1]: uint32_t = 65535 maxComputeWorkGroupCount[2]: uint32_t = 65535
vkCmdDispatch
иметь размер в x = pow(2, 25), y = 1, z = 1
На основании предоставленной вами информации groupCountX
= 225 = 33554432, но предел maxComputeWorkGroupCount[0]
= 65535 = 216-1.
Спецификация Vulkan Valid Usage для vkCmdDispatch гласит:
groupCountX
должно быть меньше или равноVkPhysicalDeviceLimits::maxComputeWorkGroupCount[0]
Нарушение допустимого использования - неопределенное поведение. "Неопределенное поведение" означает что угодно, от "все работает нормально" до "ваш компьютер падает в черную дыру и разрушает эту солнечную систему". В любом случае нарушение Valid Usage является логической ошибкой кода приложения.