Vulkan Samples 阅读 -- Performance(一): Multi Threaded & Instancing & Indirect Drawing

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的执行次数
	// 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

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
  • 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
      • vkCmdEndRenderPass
      • vkEndCommandBuffer

render

  • draw
  • updateUniformBuffer

shader

  • 基础渲染方式,但是在渲染instance rocks时将instance 的数据以VBO的形式传入管线

小结

   Indirect Drawing 是 instance 渲染一种扩展。能在一次渲染中为多个 mesh 绘制多个instance.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
realesrgan-ncnn-vulkan-20211212-windows是一个基于ncnn框架和Vulkan图形API开发的图像超分辨率增强模型。它是由GitHub用户realsrgan开发的最新版本,最新发布日期为2021年12月12日,专为Windows操作系统而设计。 该模型的主要应用是图像超分辨率增强,通过提高图像的分辨率和细节,使图像看起来更加清晰和真实。它采用深度学习和卷积神经网络等先进的技术,能够将低分辨率的图像转换成高分辨率的图像,从而提升图像的质量和视觉效果。 realesrgan-ncnn-vulkan-20211212-windows的开发使用了ncnn框架和Vulkan图形API,这使得它能够在Windows系统上实现快速且高效的图像处理。ncnn是一个轻量级的深度学习框架,专注于在移动平台和嵌入式设备上实现高性能和低延迟的推理。而Vulkan图形API是一种跨平台的图形渲染和计算API,可以充分利用计算设备的性能,提供高效的图像处理和渲染能力。 realesrgan-ncnn-vulkan-20211212-windows的使用可以通过命令行或者图形界面进行,用户可以根据自己的需求和偏好选择适合的方式。该模型提供了训练好的权重参数,用户可以直接加载这些参数并进行图像超分辨率增强。此外,该模型还支持批量处理和视频处理,方便用户对多个图像进行处理。 总之,realesrgan-ncnn-vulkan-20211212-windows是一个高效、快速且易于使用的图像超分辨率增强模型,适用于Windows系统,并利用了ncnn框架和Vulkan图形API的优势,为用户提供了出色的图像处理效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值