目录
Multi Threaded
prepare
- vkCreateFence: Create a fence for synchronization
- loadAssets: 加载模型和星空纹理
- setupPipelineLayout: 这里用常量赋值矩阵
- vkCreatePipelineLayout
- preparePipelines:
- vkCreateGraphicsPipelines: 画模型
- vkCreateGraphicsPipelines: 画星空
- prepareMultiThreadedRenderer: 多线程commandbuffer的创建
- commandBufferAllocateInfo
- vkAllocateCommandBuffers: 主线程buffer
- vkAllocateCommandBuffers: 子线程画背景buffer
- vkAllocateCommandBuffers: 子线程uibuffer
- threadData.resize(numThreads);
- loop numThreads
- commandPoolCreateInfo
- vkCreateCommandPool: 创建线程使用的池
- thread->commandBuffer.resize(numObjectsPerThread)
- commandBufferAllocateInfo: 每个渲染对象对应的子线程创建commandBuffer
- vkAllocateCommandBuffers
- thread->pushConstBlock.resize(numObjectsPerThread)
- thread->objectData.resize(numObjectsPerThread)
- loop numObjectsPerThread
- thread->objectData: 写数据(随机参数)
- updateMatrices
- MVP矩阵
- frustum.update(matrices.projection * matrices.view):视锥类要注意
render
- draw:多线程主要在draw
- 等待信号
VkResult fenceRes; do { fenceRes = vkWaitForFences(device, 1, &renderFence, VK_TRUE, 100000000); } while (fenceRes == VK_TIMEOUT); VK_CHECK_RESULT(fenceRes); vkResetFences(device, 1, &renderFence);
- 等待信号
- VulkanExampleBase::prepareFrame:正常
- updateCommandBuffers:这里是多线程额外增加的操作
- 先利用线程池更新子线程的secondary command buffers
- 再将这些buffer放入 primary command buffer
- 最后提交queue去渲染
- vkBeginCommandBuffer
- vkCmdBeginRenderPass – primaryCommandBuffer:主线程不包含任何渲染命令,只负责从secondary command buffers读取结果
- VkCommandBufferInheritanceInfo:从 secondary command buffers中继承数据
- updateSecondaryCommandBuffers
- vkBeginCommandBuffer:画星空的buffer
- vkCmdSetViewport
- vkCmdSetScissor
- vkCmdBindPipeline
- vkCmdPushConstants
- draw
- vkEndCommandBuffer
- vkBeginCommandBuffer:画ui
- vkCmdSetViewport
- vkCmdSetScissor
- vkCmdBindPipeline
- drawUI
- vkEndCommandBuffer
- commandBuffers.push_back(secondaryCommandBuffers.background):将画星空的buffer放入主线程使用的buffer
- loop:threadPool.threads[t]->addJob([=] { threadRenderCode(t, i, inheritanceInfo); });
- 循环利用线程渲染物体(很多ufo)
- threadRenderCode
- vkBeginCommandBuffer
- vkCmdSetViewport
- vkCmdSetScissor
- vkCmdBindPipeline
- vkCmdPushConstants
- vkCmdBindVertexBuffers
- vkCmdBindIndexBuffer
- vkCmdDrawIndexed
- vkEndCommandBuffer
- threadPool.wait()
- loop commandBuffers存入所有物体的command
- commandBuffers.push_back(secondaryCommandBuffers.ui):将画UI放入commandBuffers
- vkCmdExecuteCommands–primaryCommandBuffer
- vkCmdEndRenderPass – primaryCommandBuffer
- vkQueueSubmit:正常
- submitInfo.pCommandBuffers = &primaryCommandBuffer:只需提交主线程buffer即可
- VulkanExampleBase::submitFrame:正常
- updateMatrices
shader
- 基础渲染方式
小结
多线程渲染和正常渲染流程有些不同,在prepare阶段不用设置Descriptor相关内容。渲染时注意,主线程只负责从子线程中读取结果,而不负责任何渲染任务。
Instancing
prepare
- loadAssets: 加载模型和纹理
- prepareInstanceData
- std::vector instanceData:这里初始化所有instance,Instanced data is static, copy to device local memory
- createBuffer:创建stagingBuffer HOST
- createBuffer:创建stagingBuffer DEVICE
- createCommandBuffer:Copy to staging buffer
- vkCmdCopyBuffer
- flushCommandBuffer
- vkDestroyBuffer
- vkFreeMemory
- prepareUniformBuffers
- updateUniformBuffer
- setupDescriptorSetLayout
- vkCreateDescriptorSetLayout
- vkCreatePipelineLayout
- preparePipelines:
- vkCreateGraphicsPipelines: 画Instancing
- vertexBindingDescriptionCount控制vs的执行次数
- vkCreateGraphicsPipelines: 画Instancing
// Use all input bindings and attribute descriptions
inputState.vertexBindingDescriptionCount = static_cast<uint32_t>(bindingDescriptions.size());
inputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
-
vkCreateGraphicsPipelines: 画Planet
-
vkCreateGraphicsPipelines:画Star
-
setupDescriptorPool
-
setupDescriptorSet
- vkAllocateDescriptorSets: Instanced rocks
- vkAllocateDescriptorSets: Planet
- vkUpdateDescriptorSets
-
buildCommandBuffers
- loop drawCmdBuffers
- vkBeginCommandBuffer
- vkCmdBeginRenderPass
- vkCmdSetViewport
- vkCmdSetScissor
- Star field
- vkCmdBindDescriptorSets
- vkCmdBindPipeline
- vkCmdDraw
- Planet
- vkCmdBindDescriptorSets
- vkCmdBindPipeline
- draw
- Instanced rocks
- vkCmdBindDescriptorSets
- vkCmdBindPipeline
- vkCmdBindVertexBuffers: rock.vertices
- vkCmdBindVertexBuffers: instanceBuffer.buffer
- vkCmdBindIndexBuffer
- vkCmdDrawIndexed
- drawUI(drawCmdBuffers[i])
- vkCmdEndRenderPass
- vkEndCommandBuffer
- loop drawCmdBuffers
render
- draw
- updateUniformBuffer
shader
- 基础渲染方式,但是在渲染instance rocks时将instance 的数据以VBO的形式传入管线
小结
本节主要讲使用instance渲染更多物体。重点是自定义数据如何进入管线的(VBO)。
Indirect Drawing
prepare
- loadAssets: 加载模型和纹理
- prepareIndirectData
- loop 模型初始化indirectCommand并计算indirectCommand个数
- stagingBuffer: 创建stagingbuffer
- copyBuffer:将stagingbuffer 复制到 INDIRECT_BUFFER
- stagingBuffer.destroy
- prepareInstanceData: Indirect Drawing 在一次绘制调用中为不同的网格绘制多个实例
- std::vector instanceData:这里初始化所有instance,Instanced data is static, copy to device local memory
- createBuffer:创建stagingBuffer HOST
- createBuffer:创建stagingBuffer DEVICE
- copyBuffer
- createCommandBuffer:Copy to staging buffer
- vkCmdCopyBuffer
- flushCommandBuffer
- vkDestroyBuffer
- vkFreeMemory
- prepareUniformBuffers
- updateUniformBuffer
- setupDescriptorSetLayout
- vkCreateDescriptorSetLayout
- vkCreatePipelineLayout
- preparePipelines:
- vkCreateGraphicsPipelines: 画Indirect (Instancing)
- vertexBindingDescriptionCount控制vs的执行次数
- vkCreateGraphicsPipelines: 画Ground
- vkCreateGraphicsPipelines:画Skysphere
- vkCreateGraphicsPipelines: 画Indirect (Instancing)
- setupDescriptorPool
- setupDescriptorSet
- vkAllocateDescriptorSets
- vkUpdateDescriptorSets
- buildCommandBuffers
- loop drawCmdBuffers
- vkBeginCommandBuffer
- vkCmdBeginRenderPass
- vkCmdSetViewport
- vkCmdSetScissor
- vkCmdBindDescriptorSets
- Skysphere
- vkCmdBindPipeline
- draw
- Ground
- vkCmdBindPipeline
- draw
- Instanced
- vkCmdBindPipeline
- vkCmdBindVertexBuffers
- vkCmdBindVertexBuffers
- vkCmdBindIndexBuffer
- if support
- vkCmdDrawIndexedIndirect (间接渲染)
- else
- loop
- vkCmdDrawIndexedIndirect
- loop
- vkCmdEndRenderPass
- vkEndCommandBuffer
- loop drawCmdBuffers
render
- draw
- updateUniformBuffer
shader
- 基础渲染方式,但是在渲染instance rocks时将instance 的数据以VBO的形式传入管线
小结
Indirect Drawing 是 instance 渲染一种扩展。能在一次渲染中为多个 mesh 绘制多个instance.