[go: up one dir, main page]

Skip to content

Pipelines

A pipeline is a baked version of a program that runs on the GPU. Draw and dispatch commands run on these pipelines. Blender makes use of two type of pipelines Graphics pipelines and Compute pipelines.

Source references - gpu/vulkan/vk_pipeline_pool.hh - gpu/vulkan/vk_pipeline_pool.cc

API

classDiagram
    class VKPipelinePool{
        get_or_create_graphics_pipeline(VKGraphicsInfo, ...)
        get_or_create_compute_pipeline(VKComputeInfo, ...)

        read_from_disk()
        write_to_disk()
    }

get_or_create_*_pipeline methods are used to retrieve an already build pipeline or create a new one when the pipeline hasn't been used yet. Both use a info class that contains all the variables to identify pipelines and to construct a new one. It is a subset when Vulkan uses in the vkCreateGraphicsPipeline and vkCreateComputePipeline functions as we want to keep these structs small so lookup can be fast.

Graphic pipeline

A graphics pipeline is used by draw commands. The pipeline has multiple stages including the geometry assembly, vertex stage, fragment stage, depth testing and storing the result in the frame buffer.

If these stages change a new pipeline will be created to support the change. Blender caches pipelines so when an identical pipeline is requested as a previous one it doesn't need to be baked again. Making sure that pipeline handles are 1:1 allows us to also do better scheduling as we can ground similar calls together.

classDiagram
    class VKGraphicsInfo {
        state: GPUState
        mutable_state: GPUMutableState
        vk_pipeline_layout: VkPipelineLayout
        specialization_constants: [SpecializationConstant::Value]
    }
    class VertexIn["VKGraphicsInfo::VertexIn"] {
        vk_topology: VkPrimitiveTopology
        attributes: [VkVertexInputAttributeDescription]
        bindings: [VkVertexInputBindingDescription]
    }
    class PreRasterization["VKGraphicsInfo::Prerasterization"]{
        vk_vertex_module: VkShaderModule
        vk_geometry_module: VkShaderModule
    }
    class FragmentShader["VKGraphicsInfo::FragmentShader"] {
        vk_shader_module: VkShaderModule
        viewports: [VkViewport]
        scissors: [VkRect2D]
    }
    class FragmentOut["VKGraphicsInfo::FragmentOut"] {
        depth_attachment_format: VkFormat
        stencil_attachment_format: VkFormat
        color_attachment_formats: [VkFormat]
    }

    VKGraphicsInfo *--> VertexIn
    VKGraphicsInfo *--> PreRasterization
    VKGraphicsInfo *--> FragmentShader
    VKGraphicsInfo *--> FragmentOut

Activating a different pipeline can stall the work that the GPU is currently doing.

Compute pipeline

Compute pipelines are simple as it only has a single stage. Compute pipelines only change when shader specialization is needed (Specialization constants).

classDiagram
    class VKComputeInfo {
        vk_shader_module: VkShaderModule
        vk_pipeline_layout: VkPipelineLayout
        specialization_constants: [SpecializationConstantValue]
    }

Disk cache

Blender stores a pipeline cache for the "static shaders". The file is stored in the user cache folder vk-pipeline-cache/static.bin. Pipeline caches are driver specific caches. What is included in this cache isn't standardized. It is seen as data that a driver could be stored to be reusable for the next time the same application is run.

Performance wise pipeline caches can reduce stuttering and typically don't have a large performance penalty when they need to be re-initialized (<1s during a whole Blender session).

The driver specific data is prefixed by data to identify if the cache can be used by the current driver /device combination and blender session.

packet-beta
title Blender pipeline cache file.
0-4: "#BC00"
5-8: "BLENDER_VERSION"
9-12: "BL_VERSION_PATCH"
13-21: "COMMIT HASH"
22-26: "data size"
27-31: "GPU vendor id"
32-36: "GPU device id"
37-40: "driver_version"
41-58: "pipeline cache UUID"
59-95: "Driver specific data"
  • BLENDER_VERSION, BLENDER_VERSION_PATCH and COMMIT_HASH is used to identify if Blender has changed.
  • data size contains the total number of bytes of the "Driver specific data field": To identify if driver specific data was stored completely.
  • GPU vendor id keeps track if a GPU of a different vendor is used.
  • GPU device id keeps track if a different GPU of a vendor is used.

Future

  • VK_KHR_shader_module_identifier: Blender can query the pipeline cache to check if compilation step can be skipped as the shader is part of the pipeline cache already. This could also include skipping GLSL assembly as well.
  • VK_EXT_graphics_pipeline_library: Parts of a pipeline can be shared for example the geometry assembly could be identical between other pipelines and processing done in a totally different pipeline could reduce the bake time of the pipeline.