Vulkan 围炉夜话

news2024/12/22 16:50:15

在这里插入图片描述

系列文章目录


OpenGL 围炉夜话
Vulkan 围炉夜话


文章目录

  • 系列文章目录
  • Vulkan
  • 参考书
  • 教程
  • 学习摘要
    • VkImage 、VkBuffer
      • VkImage 相关
      • VkBuffer 相关
      • VkDeviceMemory 映射
    • 理解代码流线
    • 渲染通道
      • 理解渲染通道
      • 创建渲染通道
    • VkFramebuffer 帧缓存
    • 流水线
      • 创建流水线缓冲对象(PCO) —— vkCreatePipelineCache
      • 合并流水线缓冲 —— vkMergePipelineCaches
      • 从流水线缓冲获取数据 —— vkGetPipelineCacheData
      • 创建图形流水线 —— vkCreateGraphicsPipelines
        • VkPipelineShaderStageCreateInfo —— 着色器阶段
        • VkPipelineVertexInputStateCreateInfo —— 顶点输入状态
        • VkPipelineInputAssemblyStateCreateInfo —— 输入的图元装配状态
        • VkPipelineTessellationStateCreateInfo —— 细分控件和细分计算着色器状态
        • VkPipelineViewportStateCreateInfo —— 视口状态
        • VkPipelineRasterizationStateCreateInfo —— 光栅化状态
        • VkPipelineMultisampleStateCreateInfo —— 多重采样状态
        • VkPipelineDepthStencilStateCreateInfo —— 深度、模板状态
        • VkPipelineColorBlendStateCreateInfo —— 颜色融混状态
        • VkPipelineDynamicStateCreateInfo —— 动态状态
      • 销毁流水线 —— vkDestroyPipeline
      • 创建计算流水线 —— vkCreateComputePipelines
      • 流水线状态对象
      • 创建流水线布局 —— vkCreatePipelineLayout


Vulkan

Vulkan 官网
Vulkan 参考手册 1.3

参考书

Vulkan学习指南 源码

教程

Vulkan::0.0::开始于VulKanSDK(Getting Started with the Vulkan SDK)
Vulkan Programming Guide::Chapter1::Overview of VulKan(纵观VulKan)

学习摘要

VkImage 、VkBuffer

在这里插入图片描述

VkImage 相关

    完整的图像资源创建工作流如下图:

在这里插入图片描述

  1. vkCreateImage 函数创建 VkImage 图像资源
VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(
    VkDevice                                    device,
    const VkImageCreateInfo*                    pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkImage*                                    pImage);
  1. vkAllocateMemory 函数分配内存 VkDeviceMemory
VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(
    VkDevice                                    device,
    const VkMemoryAllocateInfo*                 pAllocateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkDeviceMemory*                             pMemory);
  1. vkBindImageMemory 函数把分配的内存 VkDeviceMemory 绑定给 VkImage 使用
VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(
    VkDevice                                    device,
    VkImage                                     image,
    VkDeviceMemory                              memory,
    VkDeviceSize                                memoryOffset);
  1. 主机端要使用 VkImageView 来操作 VkImage,使用 vkCreateImageView 对两者进行关联
VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(
    VkDevice                                    device,
    const VkImageViewCreateInfo*                pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkImageView*                                pView);

VkBuffer 相关

    完整的缓存资源创建工作流如下图:

在这里插入图片描述

  1. vkCreateBuffer 函数创建 VkBuffer 缓存资源
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(
    VkDevice                                    device,
    const VkBufferCreateInfo*                   pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkBuffer*                                   pBuffer);
  1. vkAllocateMemory 函数分配内存 VkDeviceMemory
VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(
    VkDevice                                    device,
    const VkMemoryAllocateInfo*                 pAllocateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkDeviceMemory*                             pMemory);
  1. vkBindBufferMemory 函数把分配的内存 VkDeviceMemory 绑定给 VkBuffer 使用
VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(
    VkDevice                                    device,
    VkBuffer                                    buffer,
    VkDeviceMemory                              memory,
    VkDeviceSize                                memoryOffset);
  1. 可选择使用 vkCreateBufferViewVkBufferVkBufferView 进行关联
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(
    VkDevice                                    device,
    const VkBufferViewCreateInfo*               pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkBufferView*                               pView);

VkDeviceMemory 映射

  1. 映射到主机空间
VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(
    VkDevice                                    device,
    VkDeviceMemory                              memory,
    VkDeviceSize                                offset,
    VkDeviceSize                                size,
    VkMemoryMapFlags                            flags,
    void**                                      ppData);
  1. 解除映射
VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(
    VkDevice                                    device,
    VkDeviceMemory                              memory);

理解代码流线

    我们现在详细地理解一下之前的实现过程。首先创建一个 VkCreateBufferInfo 结构体,用顶点缓存的元数据填充它的内容。我们将缓存的用途类型保存在这里,用来设置顶点的信息(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)。其他用途类型可以是针对索引缓存、uniform 缓存、纹理缓存,等等。我们需要设置顶点缓存的大小(按字节)。因为并没有设置针对多队列的需求,我们可以设置共享模式为 VK_SHARING_MODE_EXCLUSIVE 。将结构体传递给 API 函数 vkCreateBuffer() ,创建顶点缓存对象(VertexBuffer::buf)。

    我们将创建的缓存对象(VertexBuffer::buf)作为参数传递给函数vkGetBufferMemoryRequirements() ,从而获取缓存分配的内存需求信息(memRqrmnt)。这个信息可以帮助系统按照合适的内存大小来分配缓存资源所需的空间。这个函数还需要用到结构体 VkCreateBufferInfo

    下一步,我们准备进行空间分配,根据之前的需求信息创建一个 VkMemoryAllocateInfo 对象(allocinfo)。我们设置分配的字节大小并且获取兼容的内存类型。内存的分配需要用到 vkAllocateMemory 函数,输入参数为 allocinfo,获得的设备内存类型为 VkDeviceMemory,保存在 VertexBuffer.mem 变量中。

    完成物理内存的分配之后,使用 vkMapMemory() 将它映射到宿主机本地内存,这样我们就可以直接将几何体数据复制到物理设备内存当中。我们将数据复制到物理设备内存之后,别忘了使用 vkUnmapMemory() 执行解除映射的操作。

    最后我们通过 vkBindBufferMemory() 函数将设备内存(VkDeviceMemory)和缓存对象(VkBuffer)相互绑定在一起。


渲染通道

理解渲染通道

    渲染通道(Render Pass)设置了准备在渲染时用到的帧缓存附件和子通道。附件,例如颜色和深度,设置了当前颜色和深度图像的数量。它设置了渲染过程中每幅图像所需使用的采样位数,以及图像内容的使用方法。它还设置了每个渲染通道实例的开始和结束部分如何处理图像数据。在指令缓存中使用的渲染通道被称作渲染通道实例。它负责管理子通道之间的依赖关系,定义附件与子通道之间的协议关系。

    渲染通道中主要包括两大部分:附件和子通道。以下针对附件和子通道进行进一步的讲解。

  1. 附件
        附件表示执行渲染指令时用到的一块表面区域(例如颜色、深度/模板,或者执行解析操作的解析附件)。附件的类型主要有以下五种:
  • 颜色附件(color attachment):颜色附件表示渲染图元数据时用到的绘制目标图像。
  • 深度附件(depth attachment):深度附件负责保存深度信息,并执行深度/模板测试操作。
  • 解析附件(resolve attachment):解析附件在子通道的末尾会自动从一个多重采样的附件降维到一个单一采样的附件。解析附件与多重采用的颜色附件对应,并且在子通道的末尾从颜色附件转换到对应的解析附件,即 vkCmdResolveImage。有一个例外情况是,有时候驱动程序可能会采用更优化的工作方式,例如同时执行溢出和解析操作。
  • 输入附件(input attachment):这里包含了一组附件并与着色器对象共享使用。输入附件有点类似一个严格定义的纹理,而着色器中执行的唯一操作就是纹素的获取(texture(tex,uv))——即按照着色器当前像素位置去读取相应的纹素数据。这里有一个理所当然的应用就是在经典的延迟渲染过程中,从 G-buffer 读取数据并进行后处理的滤波算法(无模糊等),以及光照处理等操作。
  • 保留附件(preserve attachment):在一个给定的子通道中,保留附件中的内容会始终保持不变。保留附件并不会在其他 API 中使用,它们唯一的作用是暂时保持某些附件对应的内容在当前子通道中不变(之后可能会使用)。对于桌面系统 GPU 来说这个功能可能没有什么用,因为渲染目标是直接写入到内存的。但是,对于其他系统来说,某一部分保存在芯片内存上的附件数据可能需要在某个子通道中被其他附件复用,此时不需要将附件内容重新放回到内存中。
  1. 子通道
        渲染通道中的子通道负责读取和写入到对应的附件中。当前渲染通道中的子通道的执行可以通过下面的渲染指令来完成:
  • 子通道可以从之前写入的附件(必须是保留附件)读取,然后写入到当前关联的附件。
  • 在渲染通道的实例中,子通道的附件也写入到颜色、深度和模板缓存。
  • 如果要在后续的通道中使用当前的子通道附件,应用程序需要负责确保子通道信息在使用过程中始终有效。
  • 保留附件在子通道的生命周期当中可以始终保持附件内容不变。此时子通道不会影响到被保护的附件的读写操作。换句话说,在子通道的生命周期当中,附件无法被读取或者写入。

创建渲染通道

  1. vkCreateRenderPass
VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(
    VkDevice                                    device,
    const VkRenderPassCreateInfo*               pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkRenderPass*                               pRenderPass);
  1. VkRenderPassCreateInfo
typedef struct VkRenderPassCreateInfo {
    VkStructureType                   sType;
    const void*                       pNext;
    VkRenderPassCreateFlags           flags;
    uint32_t                          attachmentCount;
    const VkAttachmentDescription*    pAttachments;
    uint32_t                          subpassCount;
    const VkSubpassDescription*       pSubpasses;
    uint32_t                          dependencyCount;
    const VkSubpassDependency*        pDependencies;
} VkRenderPassCreateInfo;
  1. VkAttachmentDescription
typedef struct VkAttachmentDescription {
    VkAttachmentDescriptionFlags    flags;
    VkFormat                        format;
    VkSampleCountFlagBits           samples;
    VkAttachmentLoadOp              loadOp;
    VkAttachmentStoreOp             storeOp;
    VkAttachmentLoadOp              stencilLoadOp;
    VkAttachmentStoreOp             stencilStoreOp;
    VkImageLayout                   initialLayout;
    VkImageLayout                   finalLayout;
} VkAttachmentDescription;
  1. VkSubpassDescription
typedef struct VkSubpassDescription {
    VkSubpassDescriptionFlags       flags;
    VkPipelineBindPoint             pipelineBindPoint;
    uint32_t                        inputAttachmentCount;
    const VkAttachmentReference*    pInputAttachments;
    uint32_t                        colorAttachmentCount;
    const VkAttachmentReference*    pColorAttachments;
    const VkAttachmentReference*    pResolveAttachments;
    const VkAttachmentReference*    pDepthStencilAttachment;
    uint32_t                        preserveAttachmentCount;
    const uint32_t*                 pPreserveAttachments;
} VkSubpassDescription;
  1. VkSubpassDependency
typedef struct VkSubpassDependency {
    uint32_t                srcSubpass;
    uint32_t                dstSubpass;
    VkPipelineStageFlags    srcStageMask;
    VkPipelineStageFlags    dstStageMask;
    VkAccessFlags           srcAccessMask;
    VkAccessFlags           dstAccessMask;
    VkDependencyFlags       dependencyFlags;
} VkSubpassDependency;
  1. VkAttachmentReference
typedef struct VkAttachmentReference {
    uint32_t         attachment;
    VkImageLayout    layout;
} VkAttachmentReference;

VkFramebuffer 帧缓存

  1. vkCreateFramebuffer
VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(
    VkDevice                                    device,
    const VkFramebufferCreateInfo*              pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkFramebuffer*                              pFramebuffer);
  1. VkFramebufferCreateInfo
typedef struct VkFramebufferCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkFramebufferCreateFlags    flags;
    VkRenderPass                renderPass;
    uint32_t                    attachmentCount;
    const VkImageView*          pAttachments;
    uint32_t                    width;
    uint32_t                    height;
    uint32_t                    layers;
} VkFramebufferCreateInfo;

流水线

    流水线指的是由一系列固定阶段组成,数据流输入之后,每一个阶段对数据进行处理之后,将它传递给下一个阶段。最终的成果可以是2D的光栅化之后的绘制图形(图形流水线),也可以是通过某种计算逻辑(计算流水线)完成更新的资源信息(缓存或者图像)。

    Vulkan 支持两种类型的流水线——图形流水线和计算流水线。

  • 图形流水线(graphics pipeline):这个流水线会使用指令缓存中的一组 Vulkan 指令,将 2D/3D 场景绘制到 2D 光栅化图像上。
  • 计算流水线(compute pipeline):这个流水线使用指令缓存中的一组 Vulkan 指令,来处理计算性的工作。

    整个流水线的执行是从输入装配开始,此时输入的顶点数据会被装配成点、线、或者三角形形式的图元拓扑结构。通过可编程的顶点着色器阶段,输入的顶点数据被转换到剪切空间。几何体通过细分控制着色器和细分计算着色器两个装配阶段进行细分,而几何着色器是唯一一个可以从单一的输入图元产生多个输出图元的阶段。

    然后,我们通过图元装配环节获取前面阶段中变换坐标后的所有顶点,并且将它们按照之前输入的指定绘制/图元类型(点、线、三角形)进行排列。如果输入的顶点坐标已经在当前视口区域之外,那么对应的图元会被裁切掉,此时被裁切的片元(视口之外)也会被直接丢弃。

    光栅化即变换到屏幕坐标空间的图元(点、线、三角形)转换为离散元素(即片元)的过程。片元会交由下一个阶段进行操作,即片元着色器。片元着色器对每个单独的片元执行运算。这些片元最终会成为帧缓存的一部分,并且会再度经历一系列可能的数据更新操作,比如深度测试、模板测试,以及片元融混。

    缓存和图像内存可以放在一个独立的流水线中以 1D/2D/3D 工作组的形式进行处理,即计算流水线。计算流水线对于各种并行计算的需求来说是非常强大的。在计算流水线中可以同时修改(读/写)缓存和图像的内存数据。

    流水线中通常包括了三大基本概念:流水线状态对象流水线缓冲对象流水线布局。它们可以高效地控制底层流水线的操作:

  • 流水线状态对象(Pipeline State Object,PSO):物理设备或者 GPU 端可以直接在硬件层面执行一些特定类型的操作。这些操作包括光栅化和条件更新,比如融混、深度测试、模板化等。 Vulkan 允许我们通过 PSO 自由控制这些硬件属性设置。其他一些硬件端直接控制的操作还包括根据图元拓扑类型(点、线、三角形)进行给定几何体形状装配、视口的控制,等等。

  • 流水线缓冲对象(Pipeline Cache Object,PCO):流水线缓冲的机制可以帮助我们快速获取合复用之前的流水线。应用程序可以因此更好地避免反复创建相同或者相似的流水线对象。

  • 流水线布局(Pipeline layout):缓存和图像数据都是间接关联到着色器上的,可以通过着色器的资源变量进行访问。资源变量被关联到缓存和图像的视图对象。这些资源变量可以通过描述符和描述符的集合布局来进行管理。在流水线当中,流水线布局可以管理一系列的描述符集合布局。


vkCreatePipelineLayout,vkCreateGraphicsPipelines,vkCreateComputePipelines,vkCreatePipelineCache,vkMergePipelineCaches

创建流水线缓冲对象(PCO) —— vkCreatePipelineCache

VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(
    VkDevice                                    device,
    const VkPipelineCacheCreateInfo*            pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkPipelineCache*                            pPipelineCache);
  1. VkPipelineCacheCreateInfo
typedef struct VkPipelineCacheCreateInfo {
    VkStructureType               sType;
    const void*                   pNext;
    VkPipelineCacheCreateFlags    flags;
    size_t                        initialDataSize;
    const void*                   pInitialData;
} VkPipelineCacheCreateInfo;

合并流水线缓冲 —— vkMergePipelineCaches

VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(
    VkDevice                                    device,
    VkPipelineCache                             dstCache,
    uint32_t                                    srcCacheCount,
    const VkPipelineCache*                      pSrcCaches);

从流水线缓冲获取数据 —— vkGetPipelineCacheData

VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    size_t*                                     pDataSize,
    void*                                       pData);

创建图形流水线 —— vkCreateGraphicsPipelines

    图形流水线中包含了可编程以及固定函数的流水线阶段,此外还有渲染通道、子通道和流水线布局。可编程阶段中包含了多个着色器阶段,包括顶点、片元、细分、几何和计算着色器。固定函数阶段中包括了多个流水线状态对象(Pipeline State Object,PSO)来记录动态、顶点输入、输入装配、光栅化、融混、视口、多重采用,以及深度 —— 模板状态信息。

VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    uint32_t                                    createInfoCount,
    const VkGraphicsPipelineCreateInfo*         pCreateInfos,
    const VkAllocationCallbacks*                pAllocator,
    VkPipeline*                                 pPipelines);
  1. VkGraphicsPipelineCreateInfo
typedef struct VkGraphicsPipelineCreateInfo {
    VkStructureType                                  sType;
    const void*                                      pNext;
    VkPipelineCreateFlags                            flags;
    uint32_t                                         stageCount;			// 着色器数量
    const VkPipelineShaderStageCreateInfo*           pStages;				// 着色器阶段
    const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;		// 顶点输入状态
    const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;	// 输入装配状态
    const VkPipelineTessellationStateCreateInfo*     pTessellationState;	// 细分状态
    const VkPipelineViewportStateCreateInfo*         pViewportState;		// 视口状态
    const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;	// 光栅化状态
    const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;		// 多重采样状态
    const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;	// 深度模板状态
    const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;		// 颜色融混状态
    const VkPipelineDynamicStateCreateInfo*          pDynamicState;			// 动态状态
    VkPipelineLayout                                 layout;				// 流水线布局
    VkRenderPass                                     renderPass;			// 渲染通道
    uint32_t                                         subpass;				// 子通道
    VkPipeline                                       basePipelineHandle;
    int32_t                                          basePipelineIndex;
} VkGraphicsPipelineCreateInfo;

在这里插入图片描述

VkPipelineShaderStageCreateInfo —— 着色器阶段
typedef struct VkPipelineShaderStageCreateInfo {
    VkStructureType                     sType;
    const void*                         pNext;
    VkPipelineShaderStageCreateFlags    flags;
    VkShaderStageFlagBits               stage;
    VkShaderModule                      module;
    const char*                         pName;
    const VkSpecializationInfo*         pSpecializationInfo;
} VkPipelineShaderStageCreateInfo;

typedef struct VkSpecializationInfo {
    uint32_t                           mapEntryCount;
    const VkSpecializationMapEntry*    pMapEntries;
    size_t                             dataSize;
    const void*                        pData;
} VkSpecializationInfo;

typedef struct VkSpecializationMapEntry {
    uint32_t    constantID;
    uint32_t    offset;
    size_t      size;
} VkSpecializationMapEntry;
VkPipelineVertexInputStateCreateInfo —— 顶点输入状态
typedef struct VkPipelineVertexInputStateCreateInfo {
    VkStructureType                             sType;
    const void*                                 pNext;
    VkPipelineVertexInputStateCreateFlags       flags;
    uint32_t                                    vertexBindingDescriptionCount;
    const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
    uint32_t                                    vertexAttributeDescriptionCount;
    const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
} VkPipelineVertexInputStateCreateInfo;

typedef struct VkVertexInputBindingDescription {
    uint32_t             binding;
    uint32_t             stride;
    VkVertexInputRate    inputRate;
} VkVertexInputBindingDescription;

typedef struct VkVertexInputAttributeDescription {
    uint32_t    location;
    uint32_t    binding;
    VkFormat    format;
    uint32_t    offset;
} VkVertexInputAttributeDescription;
VkPipelineInputAssemblyStateCreateInfo —— 输入的图元装配状态
typedef struct VkPipelineInputAssemblyStateCreateInfo {
    VkStructureType                            sType;
    const void*                                pNext;
    VkPipelineInputAssemblyStateCreateFlags    flags;
    VkPrimitiveTopology                        topology;
    VkBool32                                   primitiveRestartEnable;
} VkPipelineInputAssemblyStateCreateInfo;

// 点、线、三角形
typedef enum VkPrimitiveTopology {
    VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,
    VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1,
    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5,
    VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6,
    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8,
    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9,
    VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10,
    VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF
} VkPrimitiveTopology;
VkPipelineTessellationStateCreateInfo —— 细分控件和细分计算着色器状态
typedef struct VkPipelineTessellationStateCreateInfo {
    VkStructureType                           sType;
    const void*                               pNext;
    VkPipelineTessellationStateCreateFlags    flags;
    uint32_t                                  patchControlPoints;
} VkPipelineTessellationStateCreateInfo;
VkPipelineViewportStateCreateInfo —— 视口状态
typedef struct VkPipelineViewportStateCreateInfo {
    VkStructureType                       sType;
    const void*                           pNext;
    VkPipelineViewportStateCreateFlags    flags;
    uint32_t                              viewportCount;
    const VkViewport*                     pViewports;
    uint32_t                              scissorCount;
    const VkRect2D*                       pScissors;
} VkPipelineViewportStateCreateInfo;

typedef struct VkViewport {
    float    x;
    float    y;
    float    width;
    float    height;
    float    minDepth;
    float    maxDepth;
} VkViewport;

typedef struct VkRect2D {
    VkOffset2D    offset;
    VkExtent2D    extent;
} VkRect2D;

typedef struct VkOffset2D {
    int32_t    x;
    int32_t    y;
} VkOffset2D;

typedef struct VkExtent2D {
    uint32_t    width;
    uint32_t    height;
} VkExtent2D;
VkPipelineRasterizationStateCreateInfo —— 光栅化状态
typedef struct VkPipelineRasterizationStateCreateInfo {
    VkStructureType                            sType;
    const void*                                pNext;
    VkPipelineRasterizationStateCreateFlags    flags;
    VkBool32                                   depthClampEnable;
    VkBool32                                   rasterizerDiscardEnable;
    VkPolygonMode                              polygonMode;
    VkCullModeFlags                            cullMode;
    VkFrontFace                                frontFace;
    VkBool32                                   depthBiasEnable;
    float                                      depthBiasConstantFactor;
    float                                      depthBiasClamp;
    float                                      depthBiasSlopeFactor;
    float                                      lineWidth;
} VkPipelineRasterizationStateCreateInfo;

typedef enum VkPolygonMode {
    VK_POLYGON_MODE_FILL = 0,
    VK_POLYGON_MODE_LINE = 1,
    VK_POLYGON_MODE_POINT = 2,
    VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000,
    VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF
} VkPolygonMode;

typedef enum VkCullModeFlagBits {
    VK_CULL_MODE_NONE = 0,
    VK_CULL_MODE_FRONT_BIT = 0x00000001,
    VK_CULL_MODE_BACK_BIT = 0x00000002,
    VK_CULL_MODE_FRONT_AND_BACK = 0x00000003,
    VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkCullModeFlagBits;
typedef VkFlags VkCullModeFlags;

typedef enum VkFrontFace {
    VK_FRONT_FACE_COUNTER_CLOCKWISE = 0,
    VK_FRONT_FACE_CLOCKWISE = 1,
    VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF
} VkFrontFace;
VkPipelineMultisampleStateCreateInfo —— 多重采样状态
typedef struct VkPipelineMultisampleStateCreateInfo {
    VkStructureType                          sType;
    const void*                              pNext;
    VkPipelineMultisampleStateCreateFlags    flags;
    VkSampleCountFlagBits                    rasterizationSamples;
    VkBool32                                 sampleShadingEnable;
    float                                    minSampleShading;
    const VkSampleMask*                      pSampleMask;
    VkBool32                                 alphaToCoverageEnable;
    VkBool32                                 alphaToOneEnable;
} VkPipelineMultisampleStateCreateInfo;
VkPipelineDepthStencilStateCreateInfo —— 深度、模板状态
typedef struct VkPipelineDepthStencilStateCreateInfo {
    VkStructureType                           sType;
    const void*                               pNext;
    VkPipelineDepthStencilStateCreateFlags    flags;
    VkBool32                                  depthTestEnable;
    VkBool32                                  depthWriteEnable;
    VkCompareOp                               depthCompareOp;
    VkBool32                                  depthBoundsTestEnable;
    VkBool32                                  stencilTestEnable;
    VkStencilOpState                          front;
    VkStencilOpState                          back;
    float                                     minDepthBounds;
    float                                     maxDepthBounds;
} VkPipelineDepthStencilStateCreateInfo;

typedef enum VkCompareOp {
    VK_COMPARE_OP_NEVER = 0,
    VK_COMPARE_OP_LESS = 1,
    VK_COMPARE_OP_EQUAL = 2,
    VK_COMPARE_OP_LESS_OR_EQUAL = 3,
    VK_COMPARE_OP_GREATER = 4,
    VK_COMPARE_OP_NOT_EQUAL = 5,
    VK_COMPARE_OP_GREATER_OR_EQUAL = 6,
    VK_COMPARE_OP_ALWAYS = 7,
    VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF
} VkCompareOp;

typedef struct VkStencilOpState {
    VkStencilOp    failOp;
    VkStencilOp    passOp;
    VkStencilOp    depthFailOp;
    VkCompareOp    compareOp;
    uint32_t       compareMask;
    uint32_t       writeMask;
    uint32_t       reference;
} VkStencilOpState;

typedef enum VkStencilOp {
    VK_STENCIL_OP_KEEP = 0,
    VK_STENCIL_OP_ZERO = 1,
    VK_STENCIL_OP_REPLACE = 2,
    VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3,
    VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4,
    VK_STENCIL_OP_INVERT = 5,
    VK_STENCIL_OP_INCREMENT_AND_WRAP = 6,
    VK_STENCIL_OP_DECREMENT_AND_WRAP = 7,
    VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF
} VkStencilOp;
VkPipelineColorBlendStateCreateInfo —— 颜色融混状态
typedef struct VkPipelineColorBlendStateCreateInfo {
    VkStructureType                               sType;
    const void*                                   pNext;
    VkPipelineColorBlendStateCreateFlags          flags;
    VkBool32                                      logicOpEnable;
    VkLogicOp                                     logicOp;
    uint32_t                                      attachmentCount;
    const VkPipelineColorBlendAttachmentState*    pAttachments;
    float                                         blendConstants[4];
} VkPipelineColorBlendStateCreateInfo;

typedef enum VkLogicOp {
    VK_LOGIC_OP_CLEAR = 0,
    VK_LOGIC_OP_AND = 1,
    VK_LOGIC_OP_AND_REVERSE = 2,
    VK_LOGIC_OP_COPY = 3,
    VK_LOGIC_OP_AND_INVERTED = 4,
    VK_LOGIC_OP_NO_OP = 5,
    VK_LOGIC_OP_XOR = 6,
    VK_LOGIC_OP_OR = 7,
    VK_LOGIC_OP_NOR = 8,
    VK_LOGIC_OP_EQUIVALENT = 9,
    VK_LOGIC_OP_INVERT = 10,
    VK_LOGIC_OP_OR_REVERSE = 11,
    VK_LOGIC_OP_COPY_INVERTED = 12,
    VK_LOGIC_OP_OR_INVERTED = 13,
    VK_LOGIC_OP_NAND = 14,
    VK_LOGIC_OP_SET = 15,
    VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF
} VkLogicOp;

typedef struct VkPipelineColorBlendAttachmentState {
    VkBool32                 blendEnable;
    VkBlendFactor            srcColorBlendFactor;
    VkBlendFactor            dstColorBlendFactor;
    VkBlendOp                colorBlendOp;
    VkBlendFactor            srcAlphaBlendFactor;
    VkBlendFactor            dstAlphaBlendFactor;
    VkBlendOp                alphaBlendOp;
    VkColorComponentFlags    colorWriteMask;
} VkPipelineColorBlendAttachmentState;

typedef enum VkBlendFactor {
    VK_BLEND_FACTOR_ZERO = 0,
    VK_BLEND_FACTOR_ONE = 1,
    VK_BLEND_FACTOR_SRC_COLOR = 2,
    VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3,
    VK_BLEND_FACTOR_DST_COLOR = 4,
    VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5,
    VK_BLEND_FACTOR_SRC_ALPHA = 6,
    VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7,
    VK_BLEND_FACTOR_DST_ALPHA = 8,
    VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9,
    VK_BLEND_FACTOR_CONSTANT_COLOR = 10,
    VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11,
    VK_BLEND_FACTOR_CONSTANT_ALPHA = 12,
    VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13,
    VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14,
    VK_BLEND_FACTOR_SRC1_COLOR = 15,
    VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16,
    VK_BLEND_FACTOR_SRC1_ALPHA = 17,
    VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18,
    VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF
} VkBlendFactor;

typedef enum VkBlendOp {
    VK_BLEND_OP_ADD = 0,
    VK_BLEND_OP_SUBTRACT = 1,
    VK_BLEND_OP_REVERSE_SUBTRACT = 2,
    VK_BLEND_OP_MIN = 3,
    VK_BLEND_OP_MAX = 4,
    ...
    VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF
} VkBlendOp;
VkPipelineDynamicStateCreateInfo —— 动态状态
typedef struct VkPipelineDynamicStateCreateInfo {
    VkStructureType                      sType;
    const void*                          pNext;
    VkPipelineDynamicStateCreateFlags    flags;
    uint32_t                             dynamicStateCount;
    const VkDynamicState*                pDynamicStates;
} VkPipelineDynamicStateCreateInfo;

typedef enum VkDynamicState {
    VK_DYNAMIC_STATE_VIEWPORT = 0,
    VK_DYNAMIC_STATE_SCISSOR = 1,
    VK_DYNAMIC_STATE_LINE_WIDTH = 2,
    VK_DYNAMIC_STATE_DEPTH_BIAS = 3,
    VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4,
    ...
    VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF
} VkDynamicState;

销毁流水线 —— vkDestroyPipeline

VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(
    VkDevice                                    device,
    VkPipeline                                  pipeline,
    const VkAllocationCallbacks*                pAllocator);

创建计算流水线 —— vkCreateComputePipelines

    计算流水线中包括了一个独立的静态计算着色器阶段,以及流水线布局。计算着色器阶段可以实现大量的并行计算操作。另外,它的流水线布局可以将计算流水线与描述符连接在一起。

VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    uint32_t                                    createInfoCount,
    const VkComputePipelineCreateInfo*          pCreateInfos,
    const VkAllocationCallbacks*                pAllocator,
    VkPipeline*                                 pPipelines);
  1. VkComputePipelineCreateInfo
typedef struct VkComputePipelineCreateInfo {
    VkStructureType                    sType;
    const void*                        pNext;
    VkPipelineCreateFlags              flags;
    VkPipelineShaderStageCreateInfo    stage;
    VkPipelineLayout                   layout;
    VkPipeline                         basePipelineHandle;
    int32_t                            basePipelineIndex;
} VkComputePipelineCreateInfo;

流水线状态对象

    流水线中的流水线状态对象指的是控制物理设备的硬件设置接口的方法。流水线状态对象有很多种不同的类型,采用预定义的多个阶段的顺序来执行工作。各个阶段的输入数据和资源都可以按照用户自定义的方式进行修改。每个阶段都会处理自己的输入数据并将它传递给下一个阶段。根据应用程序需求的不同,某个流水线状态阶段可以按照用户需要直接略过。

  • 动态状态:设置流水线中用到的动态状态。
  • 顶点输入状态:设置数据输入的频率和解析方法。
  • 输入装配状态:将顶点数据装配成为不同的几何图元拓扑结构(线、点、各种三角形)。
  • 光栅化状态:有关光栅化的操作,例如多边形填充的模式、面的朝向设置、裁减模式,等等。
  • 颜色融混状态:设置源片元和目标片元之间的融混因子和操作方式。
  • 视口状态:定义视口的裁切方式和维度。
  • 深度/模板状态:定义深度/模板的操作方式。
  • 多重采样状态:控制光栅化过程中的像素采样方式,实现抗锯齿的需求。

创建流水线布局 —— vkCreatePipelineLayout

VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(
    VkDevice                                    device,
    const VkPipelineLayoutCreateInfo*           pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkPipelineLayout*                           pPipelineLayout);

   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1512942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ECC算法理论,基础椭圆+曲线的形状

目录 ECC算法理论基础 椭圆+曲线的形状 DH算法:Diffie-Hellman 简称ECC ECC算法理论基础</

C++训练营:引用传递

大家好&#xff1a; 衷心希望各位点赞。 您的问题请留在评论区&#xff0c;我会及时回答。 一、引用传递 简单来说&#xff0c;“引用”就是给已有的变量起一个别名。引用并没有自己单独的内存空间&#xff0c;作为引用&#xff0c;它和原变量共用一段内存空间。引用的定义格…

Java开发从入门到精通(一):Java的基础语法知识高阶:静态数组、动态数组、代码调试

Java大数据开发和安全开发 &#xff08;一&#xff09;Java的数组1.1 静态初始化数组1.1.1 静态数组的定义1.1.2 数组的原理1.1.3 数组的访问1.1.3.1 数组的取值1.1.3.2 数组的赋值1.1.3.3 数组的长度1.1.3.4 数组的使用 1.1.4 数组的遍历1.1.3 数组的案例 1.2 动态初始化数组1…

图像压缩神器:使用wxPython和Pillow快速压缩JPEG文件

导语&#xff1a; 在数字时代&#xff0c;我们经常处理大量的图像文件&#xff0c;无论是个人照片、网络图片还是工作中的设计素材。然而&#xff0c;随着图像数量的增多&#xff0c;存储和传输这些文件可能会成为一个挑战。幸运的是&#xff0c;我们可以利用Python编程和两个强…

基于Springboot影城管理系统设计与实现

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

基于JAVA的数码产品应用平台设计与实现【附项目源码】分享

基于JAVA的数码产品应用平台设计与实现&#xff1a; 源码地址&#xff1a;https://download.csdn.net/download/weixin_43894652/88842576 基于Web的数码产品应用平台设计与实现需求文档 一、引言 随着科技的飞速发展和数码产品的普及&#xff0c;用户对于获取数码产品信息…

计算机网络面经八股-HTTP常见的状态码有哪些?

常见状态码&#xff1a; 200&#xff1a;服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。301 &#xff1a; (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时&#xff0c;会自动将请求者转到新位置。302&…

openssl3.2 - exp - export ecc pubkey from ecc priv key

文章目录 openssl3.2 - exp - export ecc pubkey from ecc priv key概述笔记END openssl3.2 - exp - export ecc pubkey from ecc priv key 概述 前面实验已经生成了ECC私钥, 现在做从ECC私钥(内容为公私钥对, 里面既有私钥信息, 也有公钥信息)导出ECC公钥. 实验对应的命令行…

Liunx文件系统和基础IO

文件系统和基础IO 基础IOc语言基础IO函数当前路径和标准流系统IO系统调用函数重定向FILE文件结构体 在谈缓存区问题理解文件系统初识inode 基础IO c语言基础IO函数 打开与关闭 FILE *fopen(char *filename, const char *mode);选项还可以是 r/w/a 意味着为可读可写打开。 2…

Java异常分类(二)

RuntimeException 运行时异常&#xff1a; 派生于 RuntimeException 的异常&#xff0c;如被 0 除、数组下标越界、空指针等&#xff0c;其产生比较频繁&#xff0c;处理麻烦&#xff0c;如果显式的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交…

Vcenter 定制创建 Rocky Linux 虚拟机

文章目录 1. 图形化安装2. 初始化配置 1. 图形化安装 2. 初始化配置 Centos 8.2 指南

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的商品识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;在零售行业的技术进步中&#xff0c;开发商品识别系统扮演着关键角色。本博文详细阐述了如何利用深度学习技术搭建一个高效的商品识别系统&#xff0c;并分享了一套完整的代码实现。系统采用了性能强劲的YOLOv8算法&#xff0c;同时对YOLOv7、YOLOv6、YOLOv5等…

RabbitMQ 面试题及答案整理,最新面试题

RabbitMQ的核心组件有哪些&#xff1f; RabbitMQ的核心组件包括&#xff1a; 1、生产者&#xff08;Producer&#xff09;&#xff1a; 生产者是发送消息到RabbitMQ的应用程序。 2、消费者&#xff08;Consumer&#xff09;&#xff1a; 消费者是接收RabbitMQ消息的应用程序…

L2-035 完全二叉树的层序遍历(Python)

L2-035 完全二叉树的层序遍历 分数 25 全屏浏览 切换布局 作者 陈越 单位 浙江大学 一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是完美二叉树。对于深度为 D 的&#xff0c;有 N 个结点的二叉树&#xff0c;若其结点对应于相同深度…

吴恩达 x Open AI ChatGPT ——如何写出好的提示词视频核心笔记

核心知识点脑图如下&#xff1a; 1、第一讲&#xff1a;课程介绍 要点1&#xff1a; 上图展示了两种大型语言模型&#xff08;LLMs&#xff09;的对比&#xff1a;基础语言模型&#xff08;Base LLM&#xff09;和指令调整语言模型&#xff08;Instruction Tuned LLM&#xff0…

[LeetCode][110]平衡二叉树

题目 110.平衡二叉树 给定一个二叉树&#xff0c;判断它是否是平衡二叉树。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,3,3,null,null,4,4] 输出&#xff1a;false 示例 3&…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统(深度学习模型+UI界面+训练数据集)

摘要&#xff1a;开发农作物害虫检测系统对于提高农业生产效率和作物产量具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个农作物害虫检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0…

惬意上手Redis

Redis介绍 Redis&#xff08;全称为REmote Dictionary Server&#xff09;是一个开源的、内存中的数据存储结构&#xff0c;主要用作应用程序缓存或快速相应数据库。 REmote Dictionary Server: 有道翻译Redis是“远程字典服务”&#xff0c;远程不过是远程访问&#xff0c;而…

大模型学习笔记六:Semantic Kernel

文章目录 一、Semantic Kernel介绍和发展1&#xff09;SK 的语言开发进展2&#xff09;SK的生态位3&#xff09;SK基础架构 二、环境搭建1&#xff09;初始化2&#xff09;Semantic Functions&#xff08;不用编写代码&#xff0c;用配置实现回调函数&#xff09;3&#xff09;…

vb oe20.03 ssh nat

环境 virtual boxopeneuler 20.03 LTS网络设置 nat 主机端口可以自行设置&#xff0c;其余三项固定不变。然后即可通过ssh进行连接。