我是靠谱客的博主 跳跃水壶,最近开发中收集的这篇文章主要介绍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;

 

最后

以上就是跳跃水壶为你收集整理的Vulkan Cookbook 第五章 15 使用纹理和统一缓冲区创建描述符使用纹理和统一缓冲区创建描述符的全部内容,希望文章能够帮你解决Vulkan Cookbook 第五章 15 使用纹理和统一缓冲区创建描述符使用纹理和统一缓冲区创建描述符所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部