Vulkan

Vulkan教程(16)Drawing a Triangle-Draw-Render and presentation

Rendering and presentation

接下来我们将使用drawFrame() 函数将三角形显示到屏幕上。

drawFrame()要做如下几件事:

1.从Swap Chain 请求一个image。

2.执行带有这个image的command buffer ,这个image曾被当做attachment存储在framebuffer中(Execute the command buffer with that image as attachment in the framebuffer)。

3.将image 返回到swap chain 等待显示。

虽然所有的操作都在一个函数里运行,但是它们的执行却是异步的,这个函数调用在它真正完成任务前就会返回,并且函数内部各个操作的执行顺序也不是确定的。这就产生了一个问题,因为我们希望后一个操作在前一个操作完成后才进行。

Vulkan教程(15)Drawing a Triangle-Draw-CommandBuffer

Command buffers(命令缓冲区)

在Vulkan中,像绘画命令、内存转换等操作并不是直接通过方法调用去完成的,而是需要把所有的操作放在Command Buffer 里。这样的一个好处就是:那些已设置好的具有难度的绘图工作都可以在多线程的情况下提前完成。

Command pools(命令池)

Command pools 管理Command buffer 的内存而且Command buffer 从Command pool中被创建。所以我们必须先来创建Command pool:

VDeleter<VkCommandPool> commandPool {device, vkDestroyCommandPool};
VkCommandPoolCreateInfo poolInfo = {};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily;

Vulkan教程(14)Drawing a Triangle-Draw-Framebuffer

上一篇:Vulakn教程(13)Drawing a Triangle-Pipeline-Render passes

Framebuffers

我们已在之前的章节中多次提到FrameBuffer 并且在创建Render Pass时,我们期望拥有一个和Swap Chain 里image具有相同格式(format)的FrameBuffer。 接下来我们就将创建这种FrameBufefr.

我们将attachments包裹在FrameBuffer中,FrameBuffer 通过引用VkImageView来关联所有的attachments。在我们案例中只有一个attachment : color attachment 。然而作为attachment的image取决于在显示的时候Swap Chain 到底返回的是哪一个image,这就意味着我们需要为Swap Chain里的每一个image 创建一个FrameBuffer。

std::vector<VDeleter<VkFramebuffer>> swapChainFramebuffers;

Vulakn教程(13)Drawing a Triangle-Pipeline-Render passes

Render Pass

在创建Pipeline 之前我们必须告诉Vulkan在渲染时要使用的FrameBuffer 附件(attachments),需要定义使用color buffer 以及 depth buffer attachments的数量,要使用多少个采样(samples)以及应该如何处理采样的内容。所有这些信息都可以填写在Render Pass里。

Attachment description

在我们的应用里只使用了一个color buffer attachment,我们用Swap Chain里的一个image 来表示这个buffer。先来看一下需要用到的结构:

typedef struct VkAttachmentDescription {
    VkAttachmentDescriptionFlags flags;
    VkFormat format;
    VkSampleCountFlagBits samples;
    VkAttachmentLoadOp loadOp;
    VkAttachmentStoreOp storeOp;

vulkan教程(12)Drawing a Triangle-Pipeline-Fixed function

Fixed functions

这一章节的内容主要是Pipeline中不可编程部分的配置。

Vertex input

VkPipelineVertexInputStateCreateInfo 代表我们传递给Vertex Shader 顶点数据的格式,它涉及以下两个方面:

1、顶点数据的描述(Bindings) :数据间的间隔,以及判断数据是顶点数据(pre-vertex)还是实例数据(pre-instance)。

2、顶点属性的描述(Attribute Descriptions):传入到Vertex Shader 里的属性(attributes)类型,从哪个Binding加载以及offset。

因为我们把顶点硬编码到Shader Code中了,所以这个结构先赋空值,当我们有需要的时候再回过头来重新审视这个结构。

VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; 
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 

vulkan教程(11)Drawing a Triangle-Pipeline-Shader Module

着色器模块 Shader modules

Vulkan 和之前的图形API有所不同,为了避免不同厂商移植代码的复杂性,Vulkan的着色器代码(shader code)采用字节码格式(bytecode) SPIR-V,而非人类可以阅读的文本格式,如GLSL(opengl 的一套体系)等。但这并不意味着我们要亲自手写字节码, 幸运的是LunarG SDK 已经提供了glslangValidator.exe ,这个程序已经在你的安装目录中了,所以我们在编写着色器程序的时候任然使用我们所熟悉的GLSL格式,glslangValidator.exe 将为我们把GLSL转换成SPIR-V。

上一篇:vulkan教程(10)Drawing a Triangle-Pipeline-Introduction

Vertex shader

vulkan教程(10)Drawing a Triangle-Pipeline-Introduction

Pipeline

前言(Introduction)

Pipeline 是指图形系统对图像信息进行一系列处理的过程,这些图像信息包括顶点信息(坐标、法向量…),像素信息(图像、纹理…)等,最终这些处理好的数据将被放到帧缓冲区(FrameBuffer)中供应用获取。

vulkan教程(10)Drawing a Triangle-Pipeline-Introduction
图1-Pipeline过程

a.输入装配器(Input assembler) : 从Vertex Buffer 或 Index Buffer 中搜集原始顶点数据。

B.顶点着色器(Vertex Shader): 每一个顶点都会运行一次Vertex Sahder,它将顶点的原始坐标(model space)转换成屏幕坐标(screen space),并为pipeline的下一个阶段提供输入。

vulkan教程(9)Drawing a Triangle-Presentation- Image views

Image views

为了使用VkImage,不管是在Swap Chain 还是在Pipeline 中,我们都必须创建VkImageView,就如同它的字面意思一样,imageView是image的一个 view.他描述了我们如何访问image、访问image的哪一部分等。

这一部分我们将创建VkImageViews , 并把它用作 color targets.

std::vector<VDeleter<VkImageView>> swapChainImageViews; //声明

需要填充的结构VkImageViewCreateInfo :

typedef struct VkImageViewCreateInfo {
    VkStructureType sType
    const void* pNext;
    VkImageViewCreateFlags flags;
    VkImage image;
    VkImageViewType viewType;
    VkFormat format;
    VkComponentMapping components;

vulkan教程(8)Drawing a Triangle--Presentation--SwapChain

SwapChain

这一章节我们将学习这样一种结构/基础(infrastructure),它能为我们提供要渲染的图片,然后渲染结的果可以显到屏幕上。这样的结构就是Swap Chain , Swap Chain必须被Vulkan显示的创建。从本质上讲,Swap Chain就是一个图片的队列(a queue of images),这里的图片等着被显示到屏幕上。我们的应用将会获得一个图片,然后绘画它,之后将它提交到队列中去。Swap Chain 通常的作用是通过屏幕刷新率(refresh rate of the screen)来同步控制图片的显示。

检查显卡是否支持 Swap chain

显卡有各种理由阻止你将images直接提交给屏幕,例如系统只是个服务器(Server),不支持显示。其次,图片显示和窗口系统(window system)以及和窗口相连的window surface密切相关。所以Swap Chain并不属于核心Vulkan 功能。这就要求必须支持VK_KHR_swapchain扩展。

我们需要检查显卡是否支持Swap chain,首先我们要有能力获取显卡的所有扩展:

vulkan教程(7)Drawing a Triangle--Presentation--Window surface

Window surface

因为Vulkan是平台(platform)无关的,它不能直接与平台窗体系统(window system)进行通信,为了连接Vulkan和窗体系统,使得被渲染后的结果显示到屏幕上,我们需要使用WSI扩展(Window System Integration extensions),在这个章节我们将使用VK_KHR_surface,它提供的VkSurfaceKHR 是对surface的一个抽象,使得我们能够将渲染后的结果放到VkSurfaceKHR上。还记得我们在之前使用GLFW创建的window吗,window将支持VkSurfaceKHR的创建。

VK_KHR_surface是一个Instance 级别的扩展,我们在创建Instance时已经通过glfwGetRequiredInstanceExtensions允许了这个扩展。

同步内容
--电子创新网--
粤ICP备12070055号