更改命令中使用的VkBuffer而不重新构建命令缓冲区?

时间:2019-07-12 15:27:39

标签: glsl gpu vulkan

这可能是X Y问题,所以这是我的问题:

我正在尝试向GPU发送命令缓冲区,以将值添加到着色器缓冲区,例如:

#version 450
#define INPUT_ARRAY_SIZE 1024
layout(std430, binding = 1) buffer InputArray{
    float array[ ];
}input_array;

void main() 
{

    uint index = gl_GlobalInvocationID.x;
    if (index >= INPUT_ARRAY_SIZE){
        return; 
    }
    InputArray.input_array[index] += 3;
}

我希望能够将用于备份着色器缓冲区的VkBuffer与其他缓冲区交换出去。即:

void addValue(device, queue, command_buffer, buffer);

void addValue(device, queue, command_buffer, descriptor_set);

我要在其中交换要添加值的其他缓冲区的位置。

不幸的是,我没有一种方法来重新记录命令缓冲区。据我所知,我的唯一选择是最大程度地减少命令缓冲区的影响(当我的调用耗时数纳秒时,这是很大的),它是使用辅助命令缓冲区,并以某种方式使用管道缓存。否则,我将不得不为每个新缓冲区创建一个命令缓冲区,当我有100多个命令时,这是不可行的。似乎也无法使用VkUpdateDescriptorSets而不进行重新录制。

有没有一种方法可以使用预先记录的命令缓冲区,并在不重新记录命令的情况下随意更改着色器缓冲区后面使用的VkBuffer

1 个答案:

答案 0 :(得分:1)

并非没有the EXT_descriptor_index extension。描述符值(它们代表的GPU资源的位置)应该在写入时烘焙到CB中,而不是从某些外部源读取。

即使使用描述符索引,也需要确保CB未被执行,然后才能更新描述符。因此,这需要GPU / CPU同步(根据信号量/提交代码的结构,它可能不好也可能不好)。

  

否则,我将不得不为每个新缓冲区创建一个命令缓冲区,当我有100多个命令时,这是不可行的。

您不应将每个命令放在其自己的缓冲区中。您应该将尽可能多的命令捆绑在一起。

通常,构建命令缓冲区的成本非常低。再加上其构造的螺纹连接,它们不应成为您的主要关注点。尤其是当命令数低至“超过100条命令”时; Vulkan用户通常每隔一帧就向CB重复发出数千条命令。