Вычислительный шейдер Vulkan не останавливается на бесконечном цикле - PullRequest
1 голос
/ 18 июня 2020

Я пытаюсь создать шейдер, который останавливает мою программу следующим образом:

#version 450

layout (local_size_x = 16, local_size_y = 16) in;

void main()
{
    while(true) {}
}

Я пытаюсь вызвать конвейер, связанный с шейдером, следующим образом:

static void GpuCompute(
    EffectFramework& frame_work,
    const std::string& shader_path)
{
    auto& pipeline = frame_work.GetPipeline(shader_path);
    auto h_interface = HardwareInterface::h_interface;
    auto& device = h_interface->GetDevice();
    auto& cmd_pool = h_interface->GetCommandPool();
    auto& cmd_buffer = h_interface->GetCmdBufferTmp();
    auto& queue = h_interface->GetQueue();

    vk::CommandBufferAllocateInfo alloc_info(
        cmd_pool, vk::CommandBufferLevel::ePrimary, 1);

    auto [result, buffers] = device.allocateCommandBuffersUnique(alloc_info);
    if(result != vk::Result::eSuccess)
        Log::RecordLogError("Failed to create command buffers");

    cmd_buffer = std::move(buffers[0]);

    vk::CommandBufferBeginInfo begin_info(
        vk::CommandBufferUsageFlagBits::eSimultaneousUse, nullptr);

    vk::FenceCreateInfo fence_create_info = {};
    fence_create_info.flags = {};
    auto[result_f, fence] = device.createFenceUnique(fence_create_info);

    if(result_f != vk::Result::eSuccess)
        Log::RecordLogError("Failed to create compute fence");

    result = cmd_buffer->begin(&begin_info);
    if(result != vk::Result::eSuccess)
        Log::RecordLogError("Failed to begin recording command buffer!");
    _SetName(device, *cmd_buffer, "compute_cmd_buffer");

    cmd_buffer->bindPipeline(vk::PipelineBindPoint::eCompute, pipeline.GetPipeline());
    cmd_buffer->dispatch(1920 / 16, 1440 / 16, 1);

    cmd_buffer->end();

    vk::SubmitInfo submit_info = {};
    submit_info.commandBufferCount = 1;
    submit_info.pCommandBuffers = &*cmd_buffer;
    queue.submit(1, &submit_info, *fence);

    device.waitForFences(1,
        &*fence,
        VK_TRUE,
        std::numeric_limits<uint64_t>::max());
}

Однако когда я запускаю свою программу, она не останавливается. Я использовал renderdo c, чтобы убедиться, что вызываю шейдер:

enter image description here

It seems that the dispatch call is using the correct shader.

введите описание изображения здесь

Так почему мой код запускается? Он должен застрять в вычислении этого l oop до тепловой смерти Вселенной.

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

1 Ответ

4 голосов
/ 18 июня 2020

создать шейдер, который останавливает мою программу

Вашей операционной системе и графическим драйверам не нравится, когда устройство, отвечающее за основной пользовательский интерфейс, перестает отвечать. Так же как и пользователи указанной операционной системы или указанных графических драйверов. Следовательно, они не позволяют вам этого делать.

Любая операция шейдера, которая выполняется «слишком долго» (как бы они это ни определяли), будет бесцеремонно завершена. Может показаться, что ваше приложение продолжает работу, как будто отправка выполнена до конца. Или вы можете потерять графический контекст. Или может произойти жесткий сброс графического процессора. своего кода. Устранение мертвого кода, как правило, работает в обратном направлении от выходных данных шейдера. Поскольку это вычислительный шейдер, его выходными данными будут записи в SSBO, вызовы imageStore или обновления c atomi. Ваш код не делает ничего из этого, поэтому ни один из его кода не имеет выходных данных, и поэтому шейдер ничего не делает.

Дело в том, что вам нужно быть намного умнее, если вы хотите чтобы взломать sh ваш графический процессор.

...