Vulkan Cookbook 第五章 15 使用纹理和统一缓冲区创建描述符

使用纹理和统一缓冲区创建描述符

译者注:示例代码点击此处

在此节实例中,我们将了解如何创建最常用的资源:组合图像采样器和统一缓冲区。我们将为它们准备描述符集布局、创建描述符池、并从中分配描述符集。然后我们将使用创建的资源更新分配的集合。这样我们以后可以将描述符集绑定到命令缓冲区并访问着色器中的资源。

怎么做...

  1. 使用所选参数创建组合图像采样器(图像,图像视图和采样器)最常用的是VK_IMAGE_TYPE_2D图像类型VK_FORMAT_R8G8B8A8_UNORM格式、VK_IMAGE_VIEW_TYPE_2D视图类型VK_IMAGE_ASPECT_COLOR_BIT应用方面、VK_FILTER_LINEAR过滤模式和VK_SAMPLER_ADDRESS_MODE_REPEAT选址模式。对于所有纹理坐标,将创建的句柄存储在名为sampler的VkSampler类型变量、名为sampled_image的vkimage类型变量和名为sampled_image_view的vkimage视图类型变量中(请参阅创建组合图像采样器内容)。
  2. 使用所选参数创建一个统一缓冲区,并将缓冲区的句柄存储在一个名为uniform_buffer的VKBuffer类型变量中(请参阅创建统一(uniform)缓冲区内容)。
  3. 创建一个名为bindings的std::vector<VkDescriptorSetLayoutBinding>。
  4. 向bindings变量添加一个具有以下值的元素:
    ·binding为0
    ·descriptorType为VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
    ·descriptorCount为1
    ·stageFlags为VK_SHADER_STAGE_FRAGMENT_BIT
    ·stageFlags为nullptr
  5. 想bindings向量添加另一个元素,并对其成员使用以下值:
    ·binding为1
    ·descriptorType为VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
    ·descriptorCount为1
    ·stageFlags为VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
    ·pImmutableSamplers为nullptr
  6. 使用bindings变量创建描述符集布局,并将其句柄存储在名为descriptor_set_layout的VkDescriptorSetLayout类型变量中(请参阅创建描述符集布局内容)。
  7. 创建一个名为descriptor_types的std::vector<VkDescriptorPoolSize>类型变量。向创建的向量添加两个元素:第一个包含VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER和1值,第二个包含VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER和1值。
  8. 创建一个描述符池,其中不能单独释放单个描述符集。并且只能分配一个描述符集。在池创建期间使用descriptor_types变量,并将其句柄存储在名为descriptor_pool的VkDescriptorPool类型变量中(请参阅创建描述符池内容)。
  9. 使用descriptor_set_layout布局变量从descriptor_pool分配一个描述符集。将创建的句柄存储在名为descriptor_sets的std::vector<VkDescriptorSet>类型变量中。(请参阅分配描述符集内容)。
  10. 创建一个名为image_descriptor_infosstd::vector<ImageDescriptorInfo>类型变量。向其中添加一个元素并为其设置以下值:
    ·TargetDescriptorSet为descriptor_sets[0]
    ·TargetDescriptorBinding为0
    ·TargetArrayElement为0
    ·TargetDescriptorType为VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
    ·向ImageInfos添加一个元素,在其中设置以下值:
        ·sampler为sampler
        ·imageView为sampled_image_view
        ·imageLayout为VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
  11. 创建一个名为buffer_descriptor_infos的std::vector<BufferDescriptorInfo>类型变量,向其中添加一个元素并为其设置以下值:
    ·TargetDescriptorSet为descriptor_sets[0]
    ·TargetDescriptorBinding为1
    ·TargetArrayElement为0
    ·TargetDescriptorType为VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
    ·向BufferInfos添加一个元素,在其中设置以下值:
        ·buffer为uniform_buffer
        ·offset为0
        ·range为VK_WHOLE_SIZE
  12. 使用image_descriptor_infos和buffer_descriptor_infos向量更新描述符集。

这个怎么运作...

要准备通常使用的描述符、组合图像采样器和统一缓冲区我们需要创建它们:

if( !CreateCombinedImageSampler( physical_device, logical_device, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, sampled_image_size, 1, 1, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
      false, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_LINEAR, VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, VK_SAMPLER_ADDRESS_MODE_REPEAT,
      VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, 0.0f, false, 1.0f, false, VK_COMPARE_OP_ALWAYS, 0.0f, 0.0f, VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, false,
      sampler, sampled_image, sampled_image_memory_object, sampled_image_view ) ) {
  return false;
}

if( !CreateUniformBuffer( physical_device, logical_device, uniform_buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, uniform_buffer, uniform_buffer_memory_object ) ) {
  return false;
}

接下来,我们准备一个布局,它将定义描述符集的内部结构:

std::vector<VkDescriptorSetLayoutBinding> bindings = { 
  { 
    0, 
    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 
    1, 
    VK_SHADER_STAGE_FRAGMENT_BIT, 
    nullptr 
  }, 
  { 
    1, 
    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 
    1, 
    VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 
    nullptr 
  } 
}; 
if( !CreateDescriptorSetLayout( logical_device, bindings, descriptor_set_layout ) ) { 
  return false; 
}

之后,我们创建一个描述符池并从中分配一个描述符集:

std::vector<VkDescriptorPoolSize> descriptor_types = {
  {
    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,                  // VkDescriptorType     type
    1                                                           // uint32_t             descriptorCount
  },
  {
    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,                          // VkDescriptorType     type
    1                                                           // uint32_t             descriptorCount
  }
};
if( !CreateDescriptorPool( logical_device, false, 1, descriptor_types, descriptor_pool ) ) {
  return false;
}

if( !AllocateDescriptorSets( logical_device, descriptor_pool, { descriptor_set_layout }, descriptor_sets ) ) {
  return false;
}

最后要做的是使用在开始时创建的资源更新描述符集:

std::vector<ImageDescriptorInfo> image_descriptor_infos = {
  {
    descriptor_sets[0],                         // VkDescriptorSet                      TargetDescriptorSet
    0,                                          // uint32_t                             TargetDescriptorBinding
    0,                                          // uint32_t                             TargetArrayElement
    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,  // VkDescriptorType                     TargetDescriptorType
    {                                           // std::vector<VkDescriptorImageInfo>   ImageInfos
      {
        sampler,                                  // VkSampler                            sampler
        sampled_image_view,                       // VkImageView                          imageView
        VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL  // VkImageLayout                        imageLayout
      }
    }
  }
};

std::vector<BufferDescriptorInfo> buffer_descriptor_infos = {
  {
    descriptor_sets[0],                         // VkDescriptorSet                      TargetDescriptorSet
    1,                                          // uint32_t                             TargetDescriptorBinding
    0,                                          // uint32_t                             TargetArrayElement
    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,          // VkDescriptorType                     TargetDescriptorType
    {                                           // std::vector<VkDescriptorBufferInfo>  BufferInfos
      {
        uniform_buffer,                           // VkBuffer                             buffer
        0,                                        // VkDeviceSize                         offset
        VK_WHOLE_SIZE                             // VkDeviceSize                         range
      }
    }
  }
};

UpdateDescriptorSets( logical_device, image_descriptor_infos, buffer_descriptor_infos, {}, {} );
return true;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值