如何一次更新乘法描述符集

时间:2018-11-23 10:57:18

标签: c++ c++11 vulkan

我从我的交换链中获得了多个渲染目标,并为每个目标创建了一个描述符集。每个renderTarget创建一个commandBuffer并绑定等效描述符的想法。现在,我想通过一次调用updateDescriptorSets来更新描述符集并使用:

std::vector<vk::WriteDescriptorSet> writes;

for( UINT32 index = 0; index < descriptorSets.size(); ++index )
{
    writes.push_back( 
        vk::WriteDescriptorSet( descriptorSets[index], 0, 0, 1, 
                                vk::DescriptorType::eStorageImage,
                                &vk::DescriptorImageInfo( vk::Sampler(), imageViews[index], vk::ImageLayout::eGeneral ),
                                nullptr,
                                nullptr ) );
}

device.updateDescriptorSets( writes.size(), writes.data(), 0, nullptr );

使用这种方法,只有队列中的最后一个renderTarget呈现所需的结果。其他的只产生黑屏。 但是当我调用updateDescriptorSets乘以倍时,所有的工作都像预期的那样:

std::vector<vk::WriteDescriptorSet> writes;

for( UINT32 index = 0; index < descriptorSets.size(); ++index )
{
    writes.push_back( 
        vk::WriteDescriptorSet( descriptorSets[index], 0, 0, 1, 
                                vk::DescriptorType::eStorageImage,
                                &vk::DescriptorImageInfo( vk::Sampler(), imageViews[index], vk::ImageLayout::eGeneral ),
                                nullptr,
                                nullptr ) );
   device.updateDescriptorSets( writes.size(), writes.data(), 0, nullptr );
   writes.clear();
}

我认为我可以一次更新乘法描述符集。因此,这是不可能的,或者是我的错误。

PS:我从vulkan SDK使用c ++标头

1 个答案:

答案 0 :(得分:2)

该错误确实存在于应用程序代码中。

问题在于vk :: DescriptorImageInfo的创建。在这两个代码示例中,该结构仅在for循环的范围内退出,而仅在vk :: WriteDescriptorSet结构中复制了指向该结构的指针。

当第一个示例中的updateDescriptorSets处理结构中的数据时,相关数据超出范围,并且指针无效。巧合的是,应用程序在循环的每次迭代中始终使用相同的内存空间,因此指针指向相同的无效空间,最后一个循环迭代的数据仍会退出该空间。这就是为什么最后一个渲染目标显示预期结果的原因。