본문 바로가기
Vulkan

9. Pipeline and Pipeline State

by SimonLee 2024. 7. 8.

Vulkan 그래픽 파이프라인은 OpenGL과 동일 합니다.

차이점은 그래픽 파이프라인의 모든 단계를 개발자가 명시적으로 설정 해야합니다.

 

파이프라인을 생성하고 바인딩 하면 파이프라인을 사용할수 있습니다.

 

Vulkan 렌더링 오버뷰는 다음과 같습니다.

Vulkan Rendering Overview

 

파이프라인은 입력 데이터가 흘러가는 일련의 고정된 스테이지를 의미합니다.

위 그림 " 노랑색 영역 Grpahic Pipeline " 에 대해서 좀 더 자세히 보면 아래와 같습니다.

 

좌측에 해당하는 영역의 빨강색에 해당하는 영역은 "프로그램 스테이지" 라고 칭하며

좌측에 해당하는 나머지지 영역은 "고정 기능 스테이지" 라고 합니다.

프로그램 스테이지는 셰이더 프로그래밍 영역이라고 보면되고 

고정 기능 스테이지의 경우 그외 나머지 입니다.

이 둘의 가장 큰 차이는 프로그램 스테이지 경우 프로그래머가 수정가능한 영역이라는 것입니다.

공통적으로 각 스테이지는 드러오는 데이터를 처리하고 이를 다음 스테이지로 넘깁니다.

 

각 스테이지에 대해 간략하게 설명하면 다음과 같습니다.

파이프라인은 입력 어셈블러 로 시작한다

입력 버텍스 데이터는 지정된 프리미티브 토폴로지를 바탕으로 점과 선, 삼각형의 형태로 조립된다.

버텍스 셰이더의 프로그램 스테이지를 사용하여 입력 버텍스의 데이터가 클리핑 공간으로 변환된다.

기하 데이터는 테셀레이션 제어 셰이더와 테셀레이션 평가 셰이더 어셈블러에서 테셀레이션 된다.

지오메트리 셰이더는 하나의 입력 프리미티브로 부터 다수개의 프리미티브를 생성한다.

래스터화는 화면 좌표로 변환된 프리미티브를 프래그먼트로 변환하는 프로세스이다.

이 프래그먼트들은 프래그 먼트 셰이더라고 하는 다음 단계에서 깊이 테스트, 스텐실 테스트, 프래그먼트 블렌딩과 같은 여러가지를 적용 후 최종 프레임버퍼를 구성한다.


벌칸은 그래픽스와 컴퓨팅 두 가지 유형의 파이프라인을 지원합니다.

- 그래픽스 파이프라인 : 커맨드 버퍼를 통해 벌칸 커맨드를 실행하여 2D 래스터 이미지를 그린다.

- 컴퓨팅 파이프라인 : 커맨드 버퍼를 통해 벌칸 커맨드를 실행하여 계산작업을 처리한다.

 

컴퓨팅 파이프라인은 여기서 다루지 않고 그래픽스 파이프라인을 다룰 것입니다.

 

그래픽스 파이프라인은 다음 항목으로 구성된다.

VkGraphicsPipelineCreateInfo 구조체가 그래픽 파이프라인 전부를 표현합니다.

각 항목은 구조체의 멤버 변수와 맵핑이 됩니다.

 

1. 프로그램 스테이지 

- 1.1 버텍스 프로그램 ( VkPipelineShaderStageCreateInfo )

- 1.2 프래그먼트 프로그램 ( VkPipelineShaderStageCreateInfo )

- 1.3 테셀레이션 프로그램 ( VkPipelineTessellationStateCreateInfo )

- 1.4 컴퓨팅 셰이더 프로그램

2. 고정기능 스테이지 ( 또는 파이프라인 스테이트 )

-  2.1 동적 스테이트 ( VkPipelineDynamicStateCreateInfo )

-  2.2  버텍스 입력 스테이트 ( VkPipelineVertexInputStateCreateInfo )

-  2.3  입력 어셈블리 스테이트 ( VkPipelineInputAssemblyStateCreateInfo )

-  2.4  래스터화 스테이트 ( VkPipelineRasterizationStateCreateInfo )

-  2.5  색상 블랜딩 스테이트 ( VkPipelineColorBlendStateCreateInfo )

-  2.6  뷰포트 스테이트 ( VkPipelineViewportStateCreateInfo )

-  2.7  깊이 스텐실 스테이트 ( VkPipelineDepthStencilStateCreateInfo )

-  2.8  멀티 샘플링 스테이트 ( VkPipelineMultisampleStateCreateInfo )

3) 렌더 패스, 서브패스 ( VkPipelineLayout )

- 렌더 패스와 서브패스는 생성한 객체를 넣어주면 됩니다.

- 생성하는 방법은 모르면 아래 레퍼런스 참조 

4) 파이프라인 레이아웃 ( VkRenderPass )

- 파이프라인 레이아웃은 생성한 객체를 넣어 줍니다.

- 생성하는 방법을 모르면 아래 레퍼런스 참조

 

1. 그래픽스 파이프라인 생성

VkPipelineLayout 타입의 layout을 세팅 하기 위해서는

디스크립터 세트 레이아웃을 먼저 생성해야 한다. 

생성하는 법은 [ Chapter 10] 을 참조하자.

 

// Provided by VK_VERSION_1_0
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;

- sType : VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO

- pNext : 확장판 구조체

- Flags : 드라이버가 파이프라인을 어떻게 생성해야 하는지의 대한 정의

-- VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT : 최적화 발생X, 파이프라인 생성 시간 줄어듬

-- VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT : 해당 파이프라인은 다른 파이프라인의 부모가 될 수 없다.

-- VK_PIPELINE_CREATE_DERIVATIVE_BIT : 파이프라인은 이 전에 생성한 파이프라인의 자식이 된다.

- stageCount : 셰이더의 개수

- pStages : 파이프라인 안에 포함해야 하는 모든 셰이더 스테이지를 나타냄 ( VkPipelineShaderStageCreateInfo )

- pVertexInputState : 버텍스 입력 파이프라인 스테이트를 지정 ( VkPipelineVertexInputStateCreateInfo

- pInputAssemblyState : 입력 어셈블리 스테이트 동작 결정 ( VkPipelineInputAssemblyStateCreateInfo )

- pTessellationState : 테셀레이션 제어 평가 셰이더 스테이지의 스테이트 지정 ( VkPipelineTessellationStateCreateInfo )

- pViewportState : viewport 스테이지 스테이트 지정

- pRasterizationState : 레스터화 스테이트 지정 ( VkPipelineRasterizationStateCreateInfo )

- pMultisampleState : 래스터화 비활성화 되있으면 이 값도 Null

- pDepthStencilState : 깊이/스텐실 스테이트 지정 ( VkPipelineDepthStencilStateCreateInfo )

- pColorBlendState : 색상 블렌딩 스테이트 지정 ( VkPipelineColorBlendStateCreateInfo )

- pDynamicState : 다른 파이프라인 스테이트와 독립적으로 변경 가능 (  VkPipelineDynamicStateCreateInfo )

- layout : 파이프라인과 디스크립터 세트가 사용하는 바인딩 위치를 지정

- renderPass : 파이프라인이 사용하는 서브패스와 첨부를 지정

- subPass : 사용할 렌더 패스의 서브패스 인덱스를 파이프라인에 알려준다.

- basePipelineHandle : 기본 파이프라인을 가리킨다.

- basePipelineIndex : 기본 파이프라인 내 pCreateInfos 파라미터의 인덱스를 지정한다.

 

 

 

파이프라인을 생성하는 함수

// Provided by VK_VERSION_1_0
VkResult vkCreateGraphicsPipelines(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    uint32_t                                    createInfoCount,
    const VkGraphicsPipelineCreateInfo*         pCreateInfos,
    const VkAllocationCallbacks*                pAllocator,
    VkPipeline*                                 pPipelines);

- device : 논리장치

- pipelineCache : 파이프라인 캐시 개체, NULL 이면 파이프라인 캐시는 파이프라인 개체생성에 사용되지 않는다.

- createInfoCount : 그래픽스 파이프라인 개수 ( VkgraphicsPipelineCreateInfo )

- pCreateInfos : 그래픽스 파이프라인 배열

- pAllocator : 호스트 메모리 할당 제어

- pPipelines : createInfoCount개의 생성된 파이프라인 개체.

 

모든 스테이지 정의할 필요는 없으며 필요한 스테이지만 활성화 하면 됩니다.

 

그래픽스 파이프라인 스테이트

벌칸 그래픽 파이프라인의 단계 입니다.

Vertex Input -> Input Assembly -> Vertex Shader -> Tessellation -> Geometry -> ViewPort -> Rasterization

-> Fragment Shader -> Multi sample -> Depth - stencil -> Color blending

 

각 단계 스테이지에 대해서 좀 더 자세히 알아 봅니다.

 

1. 프로그램 스테이지 설정

셰이더 스테이지 생성 메타 정보 구조체는 VkPipelineShaderStageCreateInfo 입니다.

이전 챕터에서 셰이더 코드를 SPIR-V 형태로 변환하고 셰이더 모듈 ( VkShaderModule )을 생성했었다.

 

해당 코드와 여러가지 input을 사용하여 프로그램 스테이지 메타데이터를 생성하자.

typedef struct VkPipelineShaderStageCreateInfo {
    VkStructureType                     sType;
    const void*                         pNext;
    VkPipelineShaderStageCreateFlags    flags;
    VkShaderStageFlagBits               stage;
    VkShaderModule                      module;
    const char*                         pName;
    const VkSpecializationInfo*         pSpecializationInfo;
} VkPipelineShaderStageCreateInfo;

- sType : VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO

- pNext : 확장 구조체 포인터

- flags : 셰이더 단계를 생성하는 방법을 지정 ( VkPipelineShaderStageCreateFlagBits )

- stage : 단일 파이프라인 단계를 지정하는 VkShaderStageFlagBits 값

- module : 셰이더 코드를 포함하는 VkShaderModule

- pName : 셰이더 진입점 이름을 지정하는 문자열 포인터

- pSpecialzationInfo : 특수화 상수 에서 설명한 대로 VkSpecialzationInfo 구조체의 대한 포인터

 

// Provided by VK_VERSION_1_0
typedef enum VkShaderStageFlagBits {
    VK_SHADER_STAGE_VERTEX_BIT = 0x00000001,
    VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002,
    VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004,
    VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008,
    VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010,
    VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
    VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F
    ....
} VkShaderStageFlagBits;

VkShaderStageFlagBits는 셰이더 모듈의 종류에 해당하는 것을 넣어주면 된다.

벌텍스 셰이더의 경우 VK_SHADER_STAGE_VERTEX_BIT 이다.

pName은 셰이더 메인함수 이름 이다.

 

생성한 VkPipelineShaderStageCreateInfo그래픽 파이프라인 메타데이터 VkGraphicsPipelineCreateInfo의 pStages로 들어가게 된다.

 

Usage >>

// Graphics VkPipeline 생성
array<VkPipelineShaderStageCreateInfo, 2> pipelineShaderStageCreateInfos {
        VkPipelineShaderStageCreateInfo{
                .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                .stage = VK_SHADER_STAGE_VERTEX_BIT,
                .module = mVertexShaderModule,
                .pName = "main"
        },
        VkPipelineShaderStageCreateInfo{
                .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
                .module = mFragmentShaderModule,
                .pName = "main"
        }
};

 

2. 버텍스 입력 스테이트

 

버텍스 입력 스테이트 ( VkPipelineVertexInputStateCreateInfo ) 는 아래 2개 디스크립션을  넣어주게 됩니다.

- 입력 바인딩 디스크립션 (VkVertexInputBindingDescription)

- 버텍스 속성 디스크립션  (VkVertexInputAttributeDescription)

 

이전 챕터 [8. Vulkan 버퍼] 에서 버텍스용 버퍼를 생성했었다.

삼각형 그리기 전 ( vkCmdDraw )

커맨드 버퍼에 버텍스 버퍼를 바인딩 한 명령어를 기억하는가 ?

vkCmdBindVertexBuffers(mCommandBuffer, 0, 1, &mVertexBuffer, &vertexBufferOffset);

두번째 인자가 firstBinding 이고 0의 의미는 0번째 버퍼를 의미한다.

벌텍스를 해당 버퍼에 전달 하기위해서는 동일한 binding 값을 넣어줘야 한다.

두개의 디스크립션 binding 값은 vkCmdBindVertexBuffers 내부 변수 firstbinding 과 동일해야 함.

 

버텍스 입력 바인딩 디스크립션

// Provided by VK_VERSION_1_0
typedef struct VkVertexInputBindingDescription {
    uint32_t             binding;
    uint32_t             stride;
    VkVertexInputRate    inputRate;
} VkVertexInputBindingDescription;

- binding : 버퍼의 바인딩 번호

- stride : 버퍼내에서 정점 레코드 사이의 바이트 간격

  스트라이드는 opengl에서 쓰는 용어와 동일

- inputRate : 버텍스 어트리뷰트의 접근하는 방법이 버텍스 인덱스 or 인스턴스 인덱스 인지 설정.

  버텍스마다 데이터를 읽으면 VK_VERTEX_INPUT_RATE_VERTEX로 설정.

 

버텍스 입력 어트리뷰트 디스크립션

// Provided by VK_VERSION_1_0
typedef struct VkVertexInputAttributeDescription {
    uint32_t    location;
    uint32_t    binding;
    VkFormat    format;
    uint32_t    offset;
} VkVertexInputAttributeDescription;

- location : 셰이더에서 어트리뷰트에 해당하는 input location number

- binding : 버텍서 데이터를 넘겨줄 버퍼의 바인딩 번호

- format : 버텍스 어트리뷰트 타입과 사이즈

- offset : 버텍스의 시작하는 요소를 기준으로 offset 값.

 

버텍스 속성 디스크립터는 셰이더에게 넘길 버텍스의 위치, 바인딩, 포맷 관련 내용이다.

location 값은 버텍스 셰이더에서 어트리뷰트 선언시 지정해준 location 값과 동일하게 해준다.

string_view vertexShaderCode = {
        "#version 310 es                                        \n"
        "                                                       \n"
        "layout(location = 0) in vec3 inPosition;               \n"
        "layout(location = 1) in vec3 inColor;                  \n"
        "                                                       \n"
        "layout(location = 0) out vec3 outColor;                \n"
        "                                                       \n"
        "void main() {                                          \n"
        "    gl_Position = vec4(inPosition, 1.0);               \n"
        "    outColor = inColor;                                \n"
        "}                                                      \n"
};

inPosition ==> VkVertexInputAttributeDescription 구조체의 location == 0

inColor ==> VkVertexInputAttributeDescription 구조체의 location == 1

 

버텍스 입력 스테이트 생성 구조체

위에서 생성한 입력 바인딩 디스크립션과 버텍스 입력 어트리뷰트 디스크립션을 넣어준다.

// Provided by VK_VERSION_1_0
typedef struct VkPipelineVertexInputStateCreateInfo {
    VkStructureType                             sType;
    const void*                                 pNext;
    VkPipelineVertexInputStateCreateFlags       flags;
    uint32_t                                    vertexBindingDescriptionCount;
    const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
    uint32_t                                    vertexAttributeDescriptionCount;
    const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
} VkPipelineVertexInputStateCreateInfo;

- sType : VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO

- pNext : 확장판 지정 구조체

- flags : 추후 사용

- vertexBindingDescriptionCount : VkVertexInputBindingDescription 배열의 개수

- pVertexBindingDescriptions : VkVertexInputBindingDescription 배열의 포인터

- vertexAttributeDescriptionCount : VkVertexInputAttributeDescription 배열의 개수

- pVertexAttributeDescriptions : VkVertexInputAttributeDescription 배열의 포인터

 

usage >>

VkVertexInputBindingDescription vertexInputBindingDescription{
        .binding = 0,
        .stride = sizeof(Vertex),
        .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
};

array<VkVertexInputAttributeDescription, 2> vertexInputAttributeDescriptions{
        VkVertexInputAttributeDescription{
                .location = 0,
                .binding = 0,
                .format = VK_FORMAT_R32G32B32_SFLOAT,
                .offset = offsetof(Vertex, position)
        },
        VkVertexInputAttributeDescription{
                .location = 1,
                .binding = 0,
                .format = VK_FORMAT_R32G32B32_SFLOAT,
                .offset = offsetof(Vertex, color)
        }
};

VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo {
    .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
    .vertexBindingDescriptionCount = 1,
    .pVertexBindingDescriptions = &vertexInputBindingDescription,
    .vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexInputAttributeDescriptions.size()),
    .pVertexAttributeDescriptions = vertexInputAttributeDescriptions.data()
};

 

 

3. 입력 어셈블리 스테이트

 

그래픽스 파이프라인이 버텍스 데이터를 받았을 때 그 상태는 조립되지 않은 레고 블록으로 채워진 바구니와 비슷하다.

이러한 버텍스들은 사용자들의 지정에 따라 점, 선, 삼각형의 변형의 형태로 연결돼 원하는 모양으로 만들어준다.

그 다음 이 모양은 래스터화 단계 영향을 주어 프리미티브에 해당하는 프래그먼트를 만든다.

 

버텍스들은 VkPipelineInputAssemblyStateCreateInfo 구조체로 지정한 입력 어셈블리 단계에서 피리미티브로 조립된다.

지정한 규칙에 따라 버텍스를 서로 연결하는 데 필요한 기본 토폴로지 정보가 포함된다.

// Provided by VK_VERSION_1_0
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,
} VkPrimitiveTopology;

Point, Line, Triangle 형태로 조립할 수 있다.

제일 많이 사용하는 건 3개의 버텍스로 내부가 채워진 삼각형이다.

- VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST

 

Tology의 대한 자세한 내용은 레퍼런스를 참고하자.

 

// Provided by VK_VERSION_1_0
typedef struct VkPipelineInputAssemblyStateCreateInfo {
    VkStructureType                            sType;
    const void*                                pNext;
    VkPipelineInputAssemblyStateCreateFlags    flags;
    VkPrimitiveTopology                        topology;
    VkBool32                                   primitiveRestartEnable;
} VkPipelineInputAssemblyStateCreateInfo;

- sType : VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE

- pNext : 확장판 구조체 포인터

- flags : 추후 사용

- topology :프리미티브 토폴로지의 유형

- primitiveRestartEnable : 프리미티브 재시작 기능에 사용될지 말지를 결정한다.

 

Usage >>

VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo{
        .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
        .topology =VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
};

 

 

4. Viewport 스테이트

랜더링의 결과가 프레임 버퍼에 어느 부분에 그려질지 정의하고 표시될 출력영역을 지정한다.

VkPipelineViewportStateCreateInfo 구조체를 사용하여 제어 된다.

이 구조체는 뷰포트와 시저링도 함께 정의된다.

viewport 스테이트를 동적 스테이트로 설정하게 되면, 런타임에 vkSetCmdViewport() 를 사용하여 설정 가능하다.

코드는 정적 스테이트로 설정한다.

뷰포트는 프레임 버퍼의 영역을 지정하고 (그릴 영역)

시저테스트는 출력이 표시될 영역을 지정한다. (그려질 영역)

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

- minDepth  : 최소 깊이 값 ( 0 ~ 1 )

- maxDepth : 최대 깊이 값 ( 0 ~ 1 )

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

- offset : 좌상단 좌표 ( x, y )

- extent : Rect의 크기 ( width, height )

// Provided by VK_VERSION_1_0
typedef struct VkPipelineViewportStateCreateInfo {
    VkStructureType                       sType;
    const void*                           pNext;
    VkPipelineViewportStateCreateFlags    flags;
    uint32_t                              viewportCount;
    const VkViewport*                     pViewports;
    uint32_t                              scissorCount;
    const VkRect2D*                       pScissors;
} VkPipelineViewportStateCreateInfo;

 

- sType : VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO

- pNext : 확장판 구조체

- flags : 추후 사용

- viewportCount : pViewports 개수

- pViewports : VkViewport 배열을 가리키는 포인터

- scissorCount : pScissors 개수

- pScissors : 직사각형의 영역( VkRect2D )을 지정하는 포인터.

Usage >>

VkViewport viewport{
        .width = static_cast<float>(extent.width),
        .height = static_cast<float>(extent.height),
        .maxDepth = 1.0f
};

VkRect2D scissor{
        .extent = extent
};

VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo{
        .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
        .viewportCount = 1,
        .pViewports = &viewport,
        .scissorCount = 1,
        .pScissors = &scissor
};

 

 

5. 래스터화 스테이트

래스터화 스테이지에서는 프리미티브 토폴로지를 사용하여 프래그먼트를 생성합니다.

래스터화 된 이미지는 그리드 방식으로 배열된 프래그먼트라는 작은 정사각형으로 구성됩니다.

프래그 먼트는 프레임버퍼의 (x, y) 위치의 조합으로 데이터와 프래그먼트 셰이더가 추가한 속성과 깊이(z) 값을 갖는다.

 

각 프리미티브 정수로 된 위치가 계산돼 프레임 버퍼 그리드 해다 포인트 또는 사각형이 된다.

위치와 함께 깊이 값이 속성과 함께 프레임 버퍼에 저장되어 최종 프래그먼트 색상을 결정하게 된다.

깊이값을 활성화/비활성화 가능하며 프래그먼트 버리기가 가능하다.

 

프래그먼트는 정사각형이 아닐 수 있다.

사각형은 안티에일리아싱과 텍스처링 과정을 단순하게 만들어 주기 때문에 사각형으로 가정한다.

죄총 계산된 프래그먼트는 프레임 버퍼의 픽셀이다.

 

래스터화의 또다른 기능은 다음과 같다.

1) 다각형 채우기 모드

보통 VK_POLYGON_MODE_FILL을 사용하며, 디버깅 용도로 line과 point를 사용한다.

// Provided by VK_VERSION_1_0
typedef enum VkPolygonMode {
    VK_POLYGON_MODE_FILL = 0,
    VK_POLYGON_MODE_LINE = 1,
    VK_POLYGON_MODE_POINT = 2,
  // Provided by VK_NV_fill_rectangle
    VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000,
} VkPolygonMode;

 

2) 컬링 모드 결정

백페이스 컬링이란 용어를 많이 들어봤을 것이다.

뒷면은 보이지 않기에 뒷면을 컬링한다는 의미이고 대부분 VK_CULL_MODE_BACK_BIT을 사용한다.

// Provided by VK_VERSION_1_0
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,
} VkCullModeFlagBits;

 

3) 앞면 결정

오른손의 법칙을 사용하므로

앞면을 결정하기 위해서 꼭지점 순서가 반시계 방향이어야 한다. (CCW)

VK_FRONT_FACE_COUNTER_CLOCKWISE 설정한다.

// Provided by VK_VERSION_1_0
typedef enum VkFrontFace {
    VK_FRONT_FACE_COUNTER_CLOCKWISE = 0,
    VK_FRONT_FACE_CLOCKWISE = 1,
} VkFrontFace;

 

레스터화 스테이트 구조체.

// Provided by VK_VERSION_1_0
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;

- pType : VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO

- pNext : 확장판 구조체 포인터

- flags : 추후 사용

- depthClamp-Enable : 깊이 값 프러스텀 z 평면으로 clamp(제한) 되는지 저장

- rasterizer-DiscardEnable : 래스터화 스테이지 도달전에, 해당 프리미티브가 처리 없이 버려질 것인지 제어

- polygonMode : 삼각형 렌더링 모드 지정 ( VkPolygonMode )

- cullMode : 프리미티브 컬링 모드 지정 ( VkCullModeFlagBits )

- frontFace : 삼각형을 구성하는 버텍스의 순서로 정면을 지정한다. ( VkFrontFace )

- depthBiasEnable : 프래그먼트 깊이 바이어스 값을 사용할지 결정

- depthBias-ConstantFactor : 프래그먼트 깊이 값에 상수 깊이 값을 더한다.

- depthBiasClamp : 프래그먼트 최고 및 최저 깊이 바이어스 값 나타낸다.

- depthBiasSLope-Factor : 프로그먼트 기울기에서 깊이 바이어스 계산에 사용될 값을 나타낸다.

- lineWidth : 선분의 래스터화에 사용될 선의 굵기를 지정하는 값.

Usage >>

VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo{
        .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
        .polygonMode = VK_POLYGON_MODE_FILL,
        .cullMode = VK_CULL_MODE_NONE,
        .lineWidth = 1.0f
};

 

 

6. 컬러 블렌딩 스테이트

블렌딩은 소스 프래그먼트가 대상 프래그먼트에 병합되는 과정으로,

블렌딩 요소에 의해 결정되는 특별한 규칙을 사용한다.

소스와 대상 모두 4개의 요소(RGBA)로 구성되는데, 이중 색상은 RGB 이고 불투명도는 A에 해당된다.

 

프레임 버퍼의 주어진 샘플 위치마다 들어오는 소스 프래그먼트(RGBA)는 대상프래그먼트 (RGBA)에 병합되고,

프레임 버퍼의 프래그먼트 위치(x, y)에 저장된다.

 

VkBlendFactor는 피연산자, VkBlendOp는 연산자이다.

여기에 나와있는 것은 일부이며, 더 많은 값은 공식 Documents를 참고하자.

VkBlendFactor

 

컬러 블렌드 어태치먼트는 ( VkPipelineColorBlendAttachmentState ) 배열로 여러개를 가질수 있다.

colorWriteMask에 해당하는 RGBA 비트가 설정되어야 색상이 표현된다.

- VK_COLOR_COMPONENT_R_BIT 

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

- blendEnable : 해당 색상 첨부에서 블렌딩을 활성화 할지를 결정, 블렌딩이 비활성화 되면 소스 프래그먼트 색상 그대로 유지

- srcColorBlendFactor : 소스 (RGB)의 계산에 적용할 블렌딩 요소 지정

- dstColorBlendFactor : 대상 (RGB)의 계산에 적용할 블렌딩 요소 지정

- colorBlendOp : 소스와 대상의 색상 계산에 적용하고 최종 색상값(RGB)을 색상 첨부에 저장하기 위한 블렌딩 요소 지정

- srcAlphaBlendFactor : 소스 알파 채널의 계산에 적용할 블렌딩 요소를 지정

- dstAlphaBlendFactor : 대상 알파 채널의 계산에 적용할 블렌딩 요소를 지정

- alphaBlendOp : 소스와 대상의 알파 채널 계산에 적용하고 최종 알파값 (RGB)를 색상 첨부에 저장하기 위한 블렌딩 요소 지정

- colorWriteMask : 이 필드는 색상 첨부 버퍼에 쓸때 사용할 색상 채널 (RGBA)의 비트 마스크 지정한다.

 

// Provided by VK_VERSION_1_0
typedef struct VkPipelineColorBlendStateCreateInfo {
    VkStructureType                               sType;
    const void*                                   pNext;
    VkPipelineColorBlendStateCreateFlags          flags;
    VkBool32                                      logicOpEnable;
    VkLogicOp                                     logicOp;
    uint32_t                                      attachmentCount;
    const VkPipelineColorBlendAttachmentState*    pAttachments;
    float                                         blendConstants[4];
} VkPipelineColorBlendStateCreateInfo;

- sType : VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_CREATE_INFO

- pNext : 확장판 지정 구조체

- Flags : 추후 사용

- logicalOpEnable : 이진 플래그로 논리 연산을 적용할지를 지정.

- logicOp - logicOpEnable : 활성화 됐을 때 적용할 논리 연산을 지정.

- attachmentCount : pAttachments 개체 요소들의 개수

- pAttachments : 구성 요소의 배열 ( VkPipelineColorBlendAttachmentState )

- blendConstants : 블렌딩 요소를 기반으로 블렌딩해서 사용하는 4개의 색상 값 (RGBA)을 나타낸다.

Usage >>

VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState{
        .colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
                          VK_COLOR_COMPONENT_G_BIT |
                          VK_COLOR_COMPONENT_B_BIT |
                          VK_COLOR_COMPONENT_A_BIT
};

VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo{
        .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
        .attachmentCount = 1,
        .pAttachments = &pipelineColorBlendAttachmentState
};

 


7. 깊이/스텐실 스테이트

깊이 테스트는 z값을 버퍼에 저장해서 픽셀마다 비교하여 중첩된 뒤에있는 픽셀은 나오지 않게합니다.

스텐실 테스트는 특정 영역에 해당하는 부분은 렌더링하지 않게 합니다.

예를들어 집 내부에 있는 창문을 보면, 집안 내부 렌더링은 창문 영역만 렌더링이 되고 나머지는 집안 내부가 보이지 않는 원리 입니다.

 

깊이 테스트 동작 방식은 다음과 같습니다.

- 깊이 테스트는 depthTestEnable = VKTrue 동작한다.

- 버퍼에 쓰는 것도 Enable 해줍니다.( depthWriteEnable = VkTrue )

- minDepthBound, maxDepthBound의 0 ~ 1의 범위 입니다.

- depthCompareOp는 depth 비교 operation 입력합니다. ( VK_COMPARE_OP_LESS )

// Provided by VK_VERSION_1_0
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,
} VkCompareOp;

 


스텐실 테스트 동작 방식은 다음과 같습니다.

- 스텐실 테스트는 stencilTestEnable= VKTrue 동작한다.
- front, back에 해당하는 VkStencilOpState 입력합니다. ( front, back은 프리미티브들이 정면, 후면 일때를 말합니다. )

- VkStencilOpState를 보면 성공할때 또는 실패할때 스텐실 버퍼에 어떻게 설정할것인지 VkStencilOp를 보면 잘 나와있음.

 

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

- failOp : 스텐실 테스트에 실패한 픽셀에 대해서 동작을 지정

- passOp : 뎁스 테스트와 스텐실 테스트에 둘 다 성공한 픽셀에 대해서 동작을 지정

- depthFailOp : 스텐실 테스트에 통과하고 뎁스 테스트에 실패한 픽셀에 대해서 동작을 지정

- compareOp : 스텐실 테스트에 사용되는 비교 연산자

- compareMask : 스텐실 테스트에 참여하는 부호 없는 정수 스텐실 값의 비트를 선택합니다

- writeMask : 스텐실 프레임버퍼 첨부 파일의 스텐실 테스트에서 업데이트된 부호 없는 정수 스텐실 값의 비트를 선택합니다.

- reference : 부호 없는 스텐실 비교에 사용되는 정수 스텐실 참조 값입니다

 

// Provided by VK_VERSION_1_0
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,
} VkStencilOp;
// Provided by VK_VERSION_1_0
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,
} VkCompareOp;

 

뎁스 스테실 스테이트 생성 메타 데이터를 생성합니다.

// Provided by VK_VERSION_1_0
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;

- sType : VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO

- pNext : 확장판 지정 구조체 포인터

- Flags : 추후 사용.

- depthTestEnable : 이진 플래그로 깊이 테스트의 활성화 지정

- depthWriteEnable : 깊이 값 버퍼에 쓰기 기능을 활성화 지정

- depthCompareOp : 깊이 값 비교 연산자 지정

- depthBoundsTestEnable : 깊이 영역 테스트를 활성화할지를 지정하는 이진 플래그

- stencilTestEnable : 스텐실 테스트 활성화 지정

- Front : 스텐실 제어의 프런트 제어에 해당.

- Back : 스텐실 제어의 백 제어에 해당

- minDepthBounds : 깊이 경계 테스트에서 최소 경계값

- maxDepthBounds : 깊이 경게 테스트에서 최대 경계값

 

Usage >>

VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo{
        .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
};

 

8. 멀티 샘플 스테이트

 

멀티 샘플링은 프리미티브 래스터화 중에 만들어진 에일리어싱 효과를 제거하는 메커니즘.

안티에일리어싱은 그래픽스 기법중 하나로, 계단 현상을 최소화 하여 화면에 표시되는 렌더링 이미지의 품질을 향상시킨다.

기본적으로 안티에일리어싱의 과정은 점 샘플링 과정이다.

곡선 모양을 생성하기에 충분하지 않은 직사각형 픽셀로 표시가 되는데,

둥근 이미지의 가장자리는 색상 변경을 통해 계단 현상을 제거하게 된다.

 

프리미티브(점, 선, 삼각형) 가 최종 프리젠테이션 픽셀로 만들어지면, 멀티 샘플링 프로세스로 처리된다.

멀티 샘플은 단일 패스에서 주어진 픽셀에 대해 계산 과정에서 두 개 이상의 샘플을 사용한다.

각 샘플링은 색상, 깊이, 스텐실 값을 독립적으로 사용할 수 있으며 하나의 통합된 색상으로 만들어진다.

프래그먼트 셰이딩이란 

멀티 샘플링은 VkPipelineMultisampleStateCreateCreateInfo 구조체를 사용해서 구성할수 있다.

 

 

// Provided by VK_VERSION_1_0
typedef enum VkSampleCountFlagBits {
    VK_SAMPLE_COUNT_1_BIT = 0x00000001,
    VK_SAMPLE_COUNT_2_BIT = 0x00000002,
    VK_SAMPLE_COUNT_4_BIT = 0x00000004,
    VK_SAMPLE_COUNT_8_BIT = 0x00000008,
    VK_SAMPLE_COUNT_16_BIT = 0x00000010,
    VK_SAMPLE_COUNT_32_BIT = 0x00000020,
    VK_SAMPLE_COUNT_64_BIT = 0x00000040,
} VkSampleCountFlagBits;

픽셀당 샘플링 영역

// Provided by VK_VERSION_1_0
typedef struct VkPipelineMultisampleStateCreateInfo {
    VkStructureType                          sType;
    const void*                              pNext;
    VkPipelineMultisampleStateCreateFlags    flags;
    VkSampleCountFlagBits                    rasterizationSamples;
    VkBool32                                 sampleShadingEnable;
    float                                    minSampleShading;
    const VkSampleMask*                      pSampleMask;
    VkBool32                                 alphaToCoverageEnable;
    VkBool32                                 alphaToOneEnable;
} VkPipelineMultisampleStateCreateInfo;

- sType : VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO

- pNext : 확장판 구조체

- flags : 추후 사용

- rasterizationSamples : 래스터화에서 사용하는 픽셀당 샘플링 수

- sampleShadingEnable : 프래그먼트 셰이딩이 샘플링 마다 수행될지, 프래그먼트마다 수행될지 결정하는데 사용

  VK_TRUE면 샘플링 마다 수행, 

- minSampleShading : 각 프래그먼트의 셰이딩에 요구되는 유일한 샘플링의 최소 값

- pSampleMask : 정적 커버리지 값으로, 래스터화에서 만들어진 커버리지 값과 AND 연산에 사용하는 비트 마스크 값이다.

- alphaToCoverageEnable : 이 필드는 프래그먼트의 첫 번째 색상 출력의 알파 요소 값을 임시 커버리지 값으로 사용할수 있는지를 지정

- alphaToOneEnable : 멀티 샘플링 커버리지 값을 프래그먼트의 첫 번째 색상 출력의 알파 값으로 대체할것인지 지정.

 

 

VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo{
        .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
        .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
};

 

9. 동적 스테이트

동적 스테이트는 런타임에 변경되는 스테이트들에 대해 파이프라인에 정보를 제공한다.

예를 들어 뷰포트와 시저링의 두가지 동적 스테이트를 포함하고 있는데,

파라메터를 통해 런타임에 변경 할 수 있다.

vkCmdSetViewport 와 vkCmdSetScissor 함수가 런타임에 변경하는 함수인데 

파이프라인에 다이나믹 스테이트를 넣어주지 않으면 동작하지 않는다.

 

// Provided by VK_VERSION_1_0
typedef struct VkPipelineDynamicStateCreateInfo {
    VkStructureType                      sType;
    const void*                          pNext;
    VkPipelineDynamicStateCreateFlags    flags;
    uint32_t                             dynamicStateCount;
    const VkDynamicState*                pDynamicStates;
} VkPipelineDynamicStateCreateInfo;

- sType : VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO

- pNext : 확장판 지정 구조체

- flags : 추후 사용

- dynamicStateCount : vKDynamicState 배열 개수

- pDynamicState : VkDynamicState 열거형 데이터의 배열로 모든 동적 스테이트를 나타낸다.

 

Usage >>

Initialize

constexpr array<VkDynamicState, 2> dynamicStates{
    VK_DYNAMIC_STATE_VIEWPORT,
    VK_DYNAMIC_STATE_SCISSOR
};

VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo{
    .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
    .dynamicStateCount = dynamicStates.size(),
    .pDynamicStates = dynamicStates.data()
};

VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo{
    .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
    .....
    .pDynamicState = &pipelineDynamicStateCreateInfo,
};

VK_CHECK_ERROR(vkCreateGraphicsPipelines(mDevice,
                                 VK_NULL_HANDLE,
                                 1,
                                 &graphicsPipelineCreateInfo,
                                 nullptr,
                                 &mPipeline));

 

렌더링 하는 부분

vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
// Viewport 설정
const VkViewport viewport{
        .x = static_cast<float>(0),
        .y = static_cast<float>(0),
        .width = static_cast<float>(mSwapChainExtent.width),
        .height = static_cast<float>(mSwapChainExtent.height),
        .maxDepth = 1.0f
};
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);

// Scissor 설정
VkRect2D scissor{
        .extent.width = mSwapChainExtent.width,
        .extent.height = mSwapChainExtent.height,
};
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);

vkCmdDraw(commandBuffer, 3, 1, 0, 0);
vkCmdEndRenderPass(commandBuffer);

 

 

2. 그래픽스 파이프라인 바인딩

그래픽스 파이프라인을 사용하기 위해서

vkCmdBeginRenderPass ~ vkCmdEndRenderPass 사이에

생성한 파이프라인을 vkCmdBindPipeline 명령어로 바인딩 해주자. 

 

vkCmdBeginRenderPass(mCommandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
....
vkCmdBindPipeline(mCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, mPipeline);
....
vkCmdEndRenderPass(mCommandBuffer);

 

--------

Reference

https://docs.vulkan.org/spec/latest/chapters/framebuffer.html#VkPipelineColorBlendStateCreateInfo

 

The Framebuffer :: Vulkan Documentation Project

The weighting functions p0, p1, and p2 are defined in table Advanced Blend Overlap Modes. In these functions, the A components of the source and destination colors are taken to indicate the portion of the pixel covered by the fragment (source) and the frag

docs.vulkan.org

 

https://subscription.packtpub.com/book/game-development/9781786469809/2/ch02lvl1sec16/fitting-it-all-together

 

Learning Vulkan

Overview of this book Vulkan, the next generation graphics and compute API, is the latest offering by Khronos. This API is the successor of OpenGL and unlike OpenGL, it offers great flexibility and high performance capabilities to control modern GPU device

subscription.packtpub.com

 

https://docs.vulkan.org/spec/latest/chapters/pipelines.html

 

Pipelines :: Vulkan Documentation Project

Each pipeline executable may have a set of statistics associated with it that are generated by the pipeline compilation process. These statistics may include things such as instruction counts, amount of spilling (if any), maximum number of simultaneous thr

docs.vulkan.org

 

https://docs.vulkan.org/spec/latest/chapters/drawing.html

 

Drawing Commands :: Vulkan Documentation Project

// Provided by VK_VERSION_1_0 typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; VkPipelineInputAssemblyStateCreateFlags is a bitmask type for setting a mask, but is currently reserved for future use.

docs.vulkan.org

https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Fixed_functions

 

Fixed functions - Vulkan Tutorial

The older graphics APIs provided default state for most of the stages of the graphics pipeline. In Vulkan you have to be explicit about most pipeline states as it'll be baked into an immutable pipeline state object. In this chapter we'll fill in all of the

vulkan-tutorial.com

https://graphicsimon.tistory.com/manage/newpost/65?type=post&returnURL=https%3A%2F%2Fgraphicsimon.tistory.com%2Fmanage%2Fposts%3Fcategory%3D1185208

 

Tistory

좀 아는 블로거들의 유용한 이야기

www.tistory.com

 

 

'Vulkan' 카테고리의 다른 글

11. Image  (0) 2024.07.21
10. Descriptor set and Descriptor set layout  (0) 2024.07.12
8. Vertex Buffer and Memory  (0) 2024.07.05
7. SPIR-V  (0) 2024.07.04
6. RenderPass  (0) 2024.07.01