C++ Vulkan计算着色器未在无限循环上暂停

C++ Vulkan计算着色器未在无限循环上暂停,c++,graphics,glsl,vulkan,compute-shader,C++,Graphics,Glsl,Vulkan,Compute Shader,我正在尝试制作一个使程序暂停的着色器,如下所示: #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) {

我正在尝试制作一个使程序暂停的着色器,如下所示:

#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());
}
但是,当我运行我的程序时,它不会停止。我使用renderdoc确保调用着色器:

调度调用似乎使用了正确的着色器

那么为什么我的代码会运行呢?它应该一直在计算这个循环,直到宇宙热死

我知道它没有停止的方式是,在调用计算着色器之后,我还在同一队列和同一区域渲染图形。据我所知,提交到同一队列的命令按顺序执行,因此该着色器应暂停整个管道。但我仍然可以很好地与我的程序交互

制作一个暂停我的程序的着色器

当负责主用户界面的设备停止响应时,您的操作系统和图形驱动程序不喜欢它。所述操作系统或所述图形驱动程序的用户也不这样做。因此,他们不允许你这么做

任何运行时间过长的着色器操作,无论它们如何定义,都将被不规则地终止。您的应用程序可能会继续运行,就好像调度执行到完成一样。或者您可能会丢失图形上下文。或者可能发生GPU硬复位

或者,着色器编译器可能只是检测到着色器没有可见的副作用,即:不写任何东西,因此它完全优化了所有代码。死代码消除往往通过从着色器的输出向后工作来实现。由于这是一个计算着色器,其输出将是写入SSBO、imageStore调用或原子更新。您的代码不执行这些操作,因此其代码没有任何输出,因此着色器不执行任何操作

关键是,如果你想使你的GPU崩溃,你必须比这聪明得多

制作一个暂停我的程序的着色器

当负责主用户界面的设备停止响应时,您的操作系统和图形驱动程序不喜欢它。所述操作系统或所述图形驱动程序的用户也不这样做。因此,他们不允许你这么做

任何运行时间过长的着色器操作,无论它们如何定义,都将被不规则地终止。您的应用程序可能会继续运行,就好像调度执行到完成一样。或者您可能会丢失图形上下文。或者可能发生GPU硬复位

或者,着色器编译器可能只是检测到着色器没有可见的副作用,即:不写任何东西,因此它完全优化了所有代码。死代码消除往往通过从着色器的输出向后工作来实现。由于这是一个计算着色器,其输出将是写入SSBO、imageStore调用或原子更新。您的代码不执行这些操作,因此其代码没有任何输出,因此着色器不执行任何操作


关键是,如果你想让GPU崩溃,你必须比这聪明得多。

我想知道Vulkan驱动程序是否在优化整个while循环,因为它不起任何作用。你能试着在循环中添加一些东西吗?也许是写一个统一的,或者只是更新一个变量?程序会在C++中做IO或改变状态;也许Vulkan使用了类似的规则。我想知道Vulkan驱动程序是否在优化整个while循环,因为它没有做任何工作。你能试着在循环中添加一些东西吗?也许是写一个统一的,或者只是更新一个变量?程序会在C++中做IO或改变状态;也许Vulkan使用了类似的规则。破坏GPU确实是最终目标破坏GPU确实是最终目标