Фрагмент шейдера для размещения зависимостей - PullRequest
2 голосов
/ 02 мая 2020

Я записываю данные в буфер хранения в фрагментном шейдере и пытаюсь прочитать данные на хосте сразу после. Если я делаю то же самое, но использую шейдер Compute, барьер работает, и я могу читать данные на хосте. Но я могу заставить его работать с проходами рендеринга.

// fragment shader
layout (set = 0, binding = 1) writeonly buffer Voxels {
  uvec4 values[10000];
} voxels;
void main() {
    uint cur = atomicAdd(voxels.count, 1);
    voxels.values[cur] = uvec4(1,2,3,4);
}

Я пытаюсь добавить барьер памяти внутри прохода рендеринга:

  VkMemoryBarrier memoryBarrier = {
    .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
    .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
    .dstAccessMask = VK_ACCESS_HOST_READ_BIT
  };
  vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);

Рендеринг (зависимость от подпроцесса)

  VkSubpassDependency subpassDependency = {
      .srcSubpass = 0,
      .dstSubpass = VK_SUBPASS_EXTERNAL,
      .srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
      .dstStageMask = VK_PIPELINE_STAGE_HOST_BIT,
      .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT,
      .dstAccessMask = VK_ACCESS_HOST_READ_BIT,
      .dependencyFlags = VK_DEPENDENCY_DEVICE_GROUP_BIT 
  };

Но я получаю ошибку от слоя проверки при записи барьера памяти. Он говорит, что мне нужна самостоятельная подпрограмма. Но у меня не может быть никакой маски хоста, если у меня есть зависимость между подпроходом 0 и подпроходом 0?

Сообщение об ошибке:

Невозможно установить барьеры во время субпрохода 0 VkRenderPass 0x61bb1e000000007b [] без указания самостоятельной зависимости. Vulkan spe c гласит: если vkCmdPipelineBarrier вызывается в экземпляре прохода рендеринга, проход рендеринга должен быть создан хотя бы с одним экземпляром VkSubpassDependency в VkRenderPassCreateInfo :: pDependencies, который выражает зависимость от текущего подпроцесса для себя и для которого srcStageMask содержит подмножество значений битов в VkSubpassDependency :: srcStageMask, dstStageMask содержит подмножество значений битов в VkSubpassDependency :: dstStageMask, равенство в VkSubpassDependency :: семейство переменных и переменных классов битовые значения в VkSubpassDependency :: srcAccessMask и член dstAccessMask каждого элемента из pMemoryBarriers и pImageMemoryBarriers содержат подмножество битовых значений в VkSubpassDependency :: dstAccessMask (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID -vkCmdenPlaylinePlayline) *

1 Ответ

1 голос
/ 02 мая 2020

vkCmdPipelineBarrier внутри Subpass называется Sub-Self-зависимостью, и поэтому не может иметь дело с чем-либо внешним по отношению к subpass, включая псевдо-конвейер Host. Вам необходимо предварительно объявить такое использование vkCmdPipelineBarrier с VkSubpassDependency, где .srcSubpass == .dstSubpass. И в такой зависимости разрешены только этапы графического конвейера.

Ваша зависимость VK_SUBPASS_EXTERNAL, кажется, уже делает все, что нужно. Так что вам нужно только удалить vkCmdPipelineBarrier, что является недопустимым использованием. Я предполагаю, что вы знаете, что вам все еще нужно следить за забором.

Я не уверен, почему у вас есть VK_DEPENDENCY_DEVICE_GROUP_BIT. Вы активно используете группы устройств?

...