Vulkan Tutorial 6 创建深度缓冲

深度缓冲是可选的,如果要绘制3D图形,可使用深度缓冲。即使交换链以后多个图像,也只需要一个深度缓冲,因为深度缓冲在绘制交换链的每个图片时,深度缓冲是可重用的。

与交换链不同,交换链是Vulkan创建内存,深度缓冲必须自己分配图片的内存来作为深度缓冲。

步骤如下:

  1. 创建深度缓冲图像对象
  2. 申请深度缓冲设备内存
  3. 将内存绑定到图像对象
  4. 创建深度缓冲图像视图

创建深度缓冲图像对象

创建深度缓冲图像对象对象也有一个Info的结构,代码如下:

VkImageCreateInfo image_info = {};
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.pNext = NULL;
image_info.imageType = VK_IMAGE_TYPE_2D;
image_info.format = VK_FORMAT_D16_UNORM;
image_info.extent.width = info.width;
image_info.extent.height = info.height;
image_info.extent.depth = 1;
image_info.mipLevels = 1;
image_info.arrayLayers = 1;
image_info.samples = NUM_SAMPLES;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
image_info.queueFamilyIndexCount = 0;
image_info.pQueueFamilyIndices = NULL;
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
image_info.flags = 0;

vkCreateImage(info.device, &image_info, NULL, &info.depth.image);

以上代码仅仅是创建了一个图像对象,并没有申请内存。需要注意的是,填入的宽高必须是窗口的宽高。

为深度缓冲申请内存

即使知道宽高信息,也不一定能准确计算具体需要申请多大内存,因为不同的GPU硬件,可能会有不同的对齐方式。所以,需要用Vulkan提供的vkGetImageMemoryRequirements()函数来获取大小:

typedef struct VkMemoryRequirements {
    VkDeviceSize    size;
    VkDeviceSize    alignment;
    uint32_t        memoryTypeBits;
} VkMemoryRequirements;

VkMemoryRequirements mem_reqs;
vkGetImageMemoryRequirements(info.device, info.depth.image, &mem_reqs);

接下来用VkMemoryRequirements来设置VkMemoryAllocateInfo的各个字段,并且申请内存:

bool memory_type_from_properties(struct sample_info &info, uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex) {
    // Search memtypes to find first index with those properties
    for (uint32_t i = 0; i < info.memory_properties.memoryTypeCount; i++) {
        if ((typeBits & 1) == 1) {
            // Type is available, does it match user properties?
            if ((info.memory_properties.memoryTypes[i].propertyFlags & requirements_mask) 
                   == requirements_mask) {
                *typeIndex = i;
                return true;
            }
        }
        typeBits >>= 1;
    }
    // No memory types matched, return failure
    return false;
}

VkMemoryAllocateInfo mem_alloc = {};
mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
mem_alloc.pNext = NULL;
mem_alloc.allocationSize = mem_reqs.size;
memory_type_from_properties(info, mem_reqs.memoryTypeBits, 
    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex);

vkAllocateMemory(info.device, &mem_alloc, NULL, &info.depth.mem);

绑定内存到深度缓冲

vkBindImageMemory(info.device, info.depth.image, info.depth.mem, 0);

创建图像视图

与交换链一样,同样需要创建一个图像视图,代码如下:

VkImageViewCreateInfo view_info = {};
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.pNext = NULL;
view_info.image = info.depth.image;
view_info.format = VK_FORMAT_D16_UNORM;
view_info.components.r = VK_COMPONENT_SWIZZLE_R;
view_info.components.g = VK_COMPONENT_SWIZZLE_G;
view_info.components.b = VK_COMPONENT_SWIZZLE_B;
view_info.components.a = VK_COMPONENT_SWIZZLE_A;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.flags = 0;

res = vkCreateImageView(info.device, &view_info, NULL, &info.depth.view);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值