vulkan从小白到专家——VulkanSwapChain

Vulkan没有默认帧缓冲区的概念,在送显上屏之前,需要一个基础结构来持有一些缓冲区。Vulkan引入了交换链的概念。
交换链本质上就是一个(用于送显上屏)图像的等待队列。应用程序获取一个图像,绘制内容,然后返回到队列。队列如何工作,队列中图像如何送显上屏 取决于交换链的配置参数。
交换链的作用就是同步图像的上屏和屏幕的刷新。

0 Surface的校验

验证GPU是否支持surface的显示,vulkan标准内没有窗体surface的概念,外在的因素不可控所以要校验,

    // Section1: check
    VkBool32 vk_queue_family_supports_present = false;
    auto hr = vkGetPhysicalDeviceSurfaceSupportKHR(device.gpuDevice_, device.queueFamilyIndex_, device.surface_, &vk_queue_family_supports_present);
    if (hr != VK_SUCCESS || !vk_queue_family_supports_present) {
   
   
        LOGE("surface not founded...");
        exit(1);
    }

这个接口第二个参数是queue的索引,多个队列需要循环遍历,手机上一般1个队列有效。

1 Surface Format相关

同样手段,先取长度 再填充vector。

    // Query the list of supported surface format and choose one we like
    uint32_t formatCount = 0;
    hr = vkGetPhysicalDeviceSurfaceFormatsKHR(device.gpuDevice_, device.surface_,
                                         &formatCount, nullptr);
    if (hr != VK_SUCCESS || formatCount == 0) {
   
   
        LOGE("could not get number of physical device formats for device");
        exit(1);
    }

    std::vector<VkSurfaceFormatKHR> formats; formats.resize(formatCount);
    vkGetPhysicalDeviceSurfaceFormatsKHR(device.gpuDevice_, device.surface_,
                                         &formatCount, formats);
    LOGI("Got %d formats", formatCount);

    // 至少必须有RGBA8888啊,
    uint32_t chosenFormat;
    for (chosenFormat = 0; chosenFormat < formatCount; chosenFormat++) {
   
   
        if (formats[chosenFormat].format == VK_FORMAT_R8G8B8A8_UNORM) break;
    }
    assert(chosenFormat < formatCount);

surfaceFormat结构里有两个字段,pixelFormat和colorSpace:

  • 格式主要sRGB最常见的,SCRGB是FP16表示每个通道,R16G16B16A16。RGB也有两种:最普通的UNORM,和非线性的,后者非常少见。
  • 颜色空间,分线性和非线性的。

关于这两个概念补充一段:

Vulkan 本身与色彩空间无关。不过,在数字电信号转换为光信号之前的某个阶段,色彩空间必须明确。这就是在交换链创建过程中需要指定色彩空间的原因。

  • imageFormat指定图像格式是什么(与vkCreateImage()中的作用相同)。
  • imageColorSpace则表示在图像呈现时,交换链 / 显示器对这些数值的解释方式。
    所以,如果使用UNORM,这意味着色彩空间未指定,数据只是普通的原始数据位。或者更确切地说,这意味着由你来负责色彩空间(前提是图像确实存储颜色信息,而不是完全其他类型的数据)。
    如果你将VK_COLOR_SPACE_SRGB_NONLINEAR_KHR与_UNORM搭配使用,这意味着交换链获取你的数据位,并在呈现时假定这些数据已经是sRGB 格式。
    如果使用的是_SRGB,那么对于交换链本身来说没有区别,但实际情况是创建的VkImages是_SRGB格式,这意味着当你使用它们时,颜色会为你进行线性化处理(与创建非交换链的VkImage时的情况相同)。

扩展一下,谈谈色域。显示器的能力,依赖于硬件是否支持,最广泛和古老的格式是sRGB,P3(广色域),BT2020,HDR10,杜比,后面几种在HDR渲染中经常遇到,目前旗舰手机都支持hdr,iphone12是第一款集采集、处理、显示的终端设备。

要正常渲染,至少得有一种格式,R8G8B8A8_UNORM,否则就退出。P40Pro手机查询到支持5种格式,

(VkSurfaceFormatKHR)  (format = VK_FORMAT_R8G8B8A8_UNORM, colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
(VkSurfaceFormatKHR)  (format = VK_FORMAT_R8G8B8A8_SRGB, colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
(VkSurfaceFormatKHR)  (format = VK_FORMAT_R5G6B5_UNORM_PACK16, colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
(VkSurfaceFormatKHR)  (format = VK_FORMAT_R16G16B16A16_SFLOAT, colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
(VkSurfaceFormatKHR)  (format = VK_FORMAT_A2B10G10R10_UNORM_PACK32, colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)

几种格式介绍:

  • 常规的至少要有RGBA8888,
  • 3th:565是压缩格式,
  • 5th:支持HDR显示需要的格式至少1010102,
  • 4th:要到HDR-vivid,则得用格式12121212,

3 SurfaceCapabilities

    VkSurfaceCapabilitiesKHR surfaceCapabilities;
    vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device.gpuDevice_, device.surface_,&surfaceCapabilities);

主要获取交换链的长度,以及渲染目标的尺寸限制。

3.1 窗口尺寸

相关的三个变量,单位都是像素,跟渲染
VkExtent2D currentExtent; 当前窗口的尺寸,可能无效,
VkExtent2D minImageExtent; 最小尺寸
VkExtent2D maxImageExtent; 最大尺寸

    // SectionX
    VkExtent2D swap_chain_extent;
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值