文章

Vulkan复习(优化)

VkCommandBuffer数组

  • acquire(请求图像)->record(录制命令)->submit(执行命令和渲染)->present(交换链交换,并被显示器读取)
  • 只有一个VkCommandBuffer时:
    • 第i+1帧acquire会正确请求到图像吗,假设上一帧的present没有执行完,行为是:等待 / 获取frontbuffer / 获取backbuffer?
      • 会等待present中交换操作完成后(frontbuffer 始终被显示器占用,我们无法获取它),而不必等待读取完成,就可以获取到新的backbuffer,在UINT64_MAX时间内会一直等待,阻塞CPU线程
    • record和 acquire和submit有同步机制吗,怎么保证record在acquire后submit前执行?
      • 有隐式同步机制,
      • acquire的等待会阻塞整个CPU线程,包括后续的record操作,
      • record是CPU命令,可以保证内部顺序,
      • 在它们执行完成后执行vkQueueSubmit,
      • acquire和submit都是GPU命令(单commondbuffer其实可以不用semaphore),无法自动保证内部执行顺序,手动用semaphore保证顺序
    • 流程:当第i帧的submit结束就可以第i+1帧的流程执行,需要等待acquire后(也就是上一帧的present后),然后record执行,submit执行
    • 下一帧的流程需要等待上一帧的完成
  • VkCommandBuffer数组时:
    • 第i+1帧acquire会正确请求到图像吗?同上
    • 和单VkCommandBuffer的区别?双缓冲下本质没有区别,虽然vkWaitForFences不会阻塞第i+1帧的执行,但vkAcquireNextImageKHR会阻塞第i+1帧的执行(因为i帧的present中交换操作没有完成,同上面一样还是需要交换完成后才能i+1帧的流程),因此本质没有改变
    • 真正可以让 CPU 与 GPU 并行是需要三缓冲实现的
  • 流程:VkCommandBuffer、VkSemaphore、VkFence都变为数组,包括初始化,使用时使用frame id,每帧流程后都会对++frame id % max frame,清理数组

重建swapchain

  • 当窗口大小改变时,窗口表面会发生变化,导致交换链大小不再与之兼容,因此要捕获此事件和重建swapchain
  • 流程:
    • 初始化窗口:glfwSetFramebufferSizeCallback当窗口大小改变时,就会调用它的回调函数,glfwSetWindowUserPointer将参数2任意用户数据指针与参数1GLFW 窗口关联,通过glfwGetWindowUserPointer获取用户指针,在回调函数中,让bool开关打开
    • 清理SwapChain:将清理操作抽象出来到函数中,包括VkSwapchainKHR,VkImageView,VkFramebuffer
    • 重新创建SwapChain:glfwGetFramebufferSize获取帧缓冲大小(单位是像素,物理大小,随窗口大小按比例改变),当宽高为0时,会等待窗口事件,不会渲染,否则清理并创建,
    • 每帧:在vkWaitForFences和vkResetFences之间(上一帧完成后),vkAcquireNextImageKHR请求可用的图像,如果VK_ERROR_OUT_OF_DATE_KHR交换链已变得与表面不兼容,就重建SwapChain,并退出函数,由于窗口未关闭,因此会继续下一次drawFrame流程

顶点数据

  • 之前顶点数据直接放在shader中,现在我们要定义在cpp中,传入到shader中
  • 流程:
    • 顶点数据:将3个顶点的位置和颜色数据存放在数组中,每个元素都是Vertex自定义类型
    • Vertex:包含位置和颜色 两个数据,
    • VkVertexInputBindingDescription顶点输入绑定,包含绑定编号,字节间隔,顶点属性寻址是依赖于逐顶点还是逐实例
    • VkVertexInputAttributeDescription顶点输入属性描述,包含数据的绑定编号,着色器输入位置编号,数据的尺寸和类型,相对于顶点输入绑定的元素起始位置的字节偏移量(通过offsetof(class 类型,类成员),获取成员的偏移量)
    • VkPipeline:在VkPipelineVertexInputStateCreateInfo中,为vertexBindingDescriptionCount,vertexAttributeDescriptionCount设置数量和数据
    • shader:把vs中定义的顶点数据删除,改为layout(location = index) in 从外部输入
本文由作者按照 CC BY 4.0 进行授权
本页总访问量