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 является логической ошибкой кода приложения.

Другие вопросы по тегам