## 26. The Framebuffer

### 26.1. Blending

Blending combines the incoming source fragment’s R, G, B, and A values with the destination R, G, B, and A values of each sample stored in the framebuffer at the fragment’s (xf,yf) location. Blending is performed for each color sample covered by the fragment, rather than just once for each fragment.

Source and destination values are combined according to the blend operation, quadruplets of source and destination weighting factors determined by the blend factors, and a blend constant, to obtain a new set of R, G, B, and A values, as described below.

Blending is computed and applied separately to each color attachment used by the subpass, with separate controls for each attachment.

Prior to performing the blend operation, signed and unsigned normalized fixed-point color components undergo an implied conversion to floating-point as specified by Conversion from Normalized Fixed-Point to Floating-Point. Blending computations are treated as if carried out in floating-point, and basic blend operations are performed with a precision and dynamic range no lower than that used to represent destination components.

Blending applies only to fixed-point and floating-point color attachments. If the color attachment has an integer format, blending is not applied.

The pipeline blend state is included in the VkPipelineColorBlendStateCreateInfo structure during graphics pipeline creation:

The VkPipelineColorBlendStateCreateInfo structure is defined as:

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 is the type of this structure.

• pNext is NULL or a pointer to an extension-specific structure.

• flags is reserved for future use.

• logicOpEnable controls whether to apply Logical Operations.

• logicOp selects which logical operation to apply.

• attachmentCount is the number of VkPipelineColorBlendAttachmentState elements in pAttachments. This value must equal the colorAttachmentCount for the subpass in which this pipeline is used.

• pAttachments: is a pointer to array of per target attachment states.

• blendConstants is an array of four values used as the R, G, B, and A components of the blend constant that are used in blending, depending on the blend factor.

Each element of the pAttachments array is a VkPipelineColorBlendAttachmentState structure specifying per-target blending state for each individual color attachment. If the independent blending feature is not enabled on the device, all VkPipelineColorBlendAttachmentState elements in the pAttachments array must be identical.

Valid Usage
• If the independent blending feature is not enabled, all elements of pAttachments must be identical

• If the logic operations feature is not enabled, logicOpEnable must be VK_FALSE

• If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value

Valid Usage (Implicit)
• sType must be VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO

• pNext must be NULL

• flags must be 0

• If attachmentCount is not 0, pAttachments must be a valid pointer to an array of attachmentCount valid VkPipelineColorBlendAttachmentState structures

typedef VkFlags VkPipelineColorBlendStateCreateFlags;

VkPipelineColorBlendStateCreateFlags is a bitmask type for setting a mask, but is currently reserved for future use.

The VkPipelineColorBlendAttachmentState structure is defined as:

typedef struct VkPipelineColorBlendAttachmentState {
VkBool32                 blendEnable;
VkBlendFactor            srcColorBlendFactor;
VkBlendFactor            dstColorBlendFactor;
VkBlendOp                colorBlendOp;
VkBlendFactor            srcAlphaBlendFactor;
VkBlendFactor            dstAlphaBlendFactor;
VkBlendOp                alphaBlendOp;
} VkPipelineColorBlendAttachmentState;
• blendEnable controls whether blending is enabled for the corresponding color attachment. If blending is not enabled, the source fragment’s color for that attachment is passed through unmodified.

• srcColorBlendFactor selects which blend factor is used to determine the source factors (Sr,Sg,Sb).

• dstColorBlendFactor selects which blend factor is used to determine the destination factors (Dr,Dg,Db).

• colorBlendOp selects which blend operation is used to calculate the RGB values to write to the color attachment.

• srcAlphaBlendFactor selects which blend factor is used to determine the source factor Sa.

• dstAlphaBlendFactor selects which blend factor is used to determine the destination factor Da.

• alphaBlendOp selects which blend operation is use to calculate the alpha values to write to the color attachment.

• colorWriteMask is a bitmask of VkColorComponentFlagBits specifying which of the R, G, B, and/or A components are enabled for writing, as described for the Color Write Mask.

Valid Usage
• If the dual source blending feature is not enabled, srcColorBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

• If the dual source blending feature is not enabled, dstColorBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

• If the dual source blending feature is not enabled, srcAlphaBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

• If the dual source blending feature is not enabled, dstAlphaBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

Valid Usage (Implicit)
• srcColorBlendFactor must be a valid VkBlendFactor value

• dstColorBlendFactor must be a valid VkBlendFactor value

• colorBlendOp must be a valid VkBlendOp value

• srcAlphaBlendFactor must be a valid VkBlendFactor value

• dstAlphaBlendFactor must be a valid VkBlendFactor value

• alphaBlendOp must be a valid VkBlendOp value

• colorWriteMask must be a valid combination of VkColorComponentFlagBits values

#### 26.1.1. Blend Factors

The source and destination color and alpha blending factors are selected from the enum:

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;

The semantics of each enum value is described in the table below:

Table 24. Blend Factors
VkBlendFactor RGB Blend Factors (Sr,Sg,Sb) or (Dr,Dg,Db) Alpha Blend Factor (Sa or Da)

VK_BLEND_FACTOR_ZERO

(0,0,0)

0

VK_BLEND_FACTOR_ONE

(1,1,1)

1

VK_BLEND_FACTOR_SRC_COLOR

(Rs0,Gs0,Bs0)

As0

VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR

(1-Rs0,1-Gs0,1-Bs0)

1-As0

VK_BLEND_FACTOR_DST_COLOR

(Rd,Gd,Bd)

VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR

(1-Rd,1-Gd,1-Bd)

VK_BLEND_FACTOR_SRC_ALPHA

(As0,As0,As0)

As0

VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA

(1-As0,1-As0,1-As0)

1-As0

VK_BLEND_FACTOR_DST_ALPHA

VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA

VK_BLEND_FACTOR_CONSTANT_COLOR

(Rc,Gc,Bc)

Ac

VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR

(1-Rc,1-Gc,1-Bc)

1-Ac

VK_BLEND_FACTOR_CONSTANT_ALPHA

(Ac,Ac,Ac)

Ac

VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA

(1-Ac,1-Ac,1-Ac)

1-Ac

VK_BLEND_FACTOR_SRC_ALPHA_SATURATE

1

VK_BLEND_FACTOR_SRC1_COLOR

(Rs1,Gs1,Bs1)

As1

VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR

(1-Rs1,1-Gs1,1-Bs1)

1-As1

VK_BLEND_FACTOR_SRC1_ALPHA

(As1,As1,As1)

As1

VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA

(1-As1,1-As1,1-As1)

1-As1

In this table, the following conventions are used:

• Rs0,Gs0,Bs0 and As0 represent the first source color R, G, B, and A components, respectively, for the fragment output location corresponding to the color attachment being blended.

• Rs1,Gs1,Bs1 and As1 represent the second source color R, G, B, and A components, respectively, used in dual source blending modes, for the fragment output location corresponding to the color attachment being blended.

• Rd,Gd,Bd and Ad represent the R, G, B, and A components of the destination color. That is, the color currently in the corresponding color attachment for this fragment/sample.

• Rc,Gc,Bc and Ac represent the blend constant R, G, B, and A components, respectively.

If the pipeline state object is created without the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled then the blend constant (Rc,Gc,Bc,Ac) is specified via the blendConstants member of VkPipelineColorBlendStateCreateInfo.

Otherwise, to dynamically set and change the blend constant, call:

void vkCmdSetBlendConstants(
VkCommandBuffer                             commandBuffer,
const float                                 blendConstants[4]);
• commandBuffer is the command buffer into which the command will be recorded.

• blendConstants is an array of four values specifying the R, G, B, and A components of the blend constant color used in blending, depending on the blend factor.

Valid Usage
• The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled

Valid Usage (Implicit)
• commandBuffer must be a valid VkCommandBuffer handle

• commandBuffer must be in the recording state

• The VkCommandPool that commandBuffer was allocated from must support graphics operations

Host Synchronization
• Host access to commandBuffer must be externally synchronized

• Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Supported Queue Types Pipeline Type

Primary
Secondary

Both

Graphics

#### 26.1.2. Dual-Source Blending

Blend factors that use the secondary color input (Rs1,Gs1,Bs1,As1) (VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, and VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA) may consume implementation resources that could otherwise be used for rendering to multiple color attachments. Therefore, the number of color attachments that can be used in a framebuffer may be lower when using dual-source blending.

Dual-source blending is only supported if the dualSrcBlend feature is enabled.

The maximum number of color attachments that can be used in a subpass when using dual-source blending functions is implementation-dependent and is reported as the maxFragmentDualSrcAttachments member of VkPhysicalDeviceLimits.

When using a fragment shader with dual-source blending functions, the color outputs are bound to the first and second inputs of the blender using the Index decoration, as described in Fragment Output Interface. If the second color input to the blender is not written in the shader, or if no output is bound to the second input of a blender, the result of the blending operation is not defined.

#### 26.1.3. Blend Operations

Once the source and destination blend factors have been selected, they along with the source and destination components are passed to the blending operations. RGB and alpha components can use different operations. Possible values of VkBlendOp, specifying the operations, are:

typedef enum VkBlendOp {
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;

The semantics of each basic blend operations is described in the table below:

Table 25. Basic Blend Operations
VkBlendOp RGB Components Alpha Component

VK_BLEND_OP_ADD

R = Rs0 × Sr + Rd × Dr
G = Gs0 × Sg + Gd × Dg
B = Bs0 × Sb + Bd × Db

A = As0 × Sa + Ad × Da

VK_BLEND_OP_SUBTRACT

R = Rs0 × Sr - Rd × Dr
G = Gs0 × Sg - Gd × Dg
B = Bs0 × Sb - Bd × Db

A = As0 × Sa - Ad × Da

VK_BLEND_OP_REVERSE_SUBTRACT

R = Rd × Dr - Rs0 × Sr
G = Gd × Dg - Gs0 × Sg
B = Bd × Db - Bs0 × Sb

A = Ad × Da - As0 × Sa

VK_BLEND_OP_MIN

R = min(Rs0,Rd)
G = min(Gs0,Gd)
B = min(Bs0,Bd)

VK_BLEND_OP_MAX

R = max(Rs0,Rd)
G = max(Gs0,Gd)
B = max(Bs0,Bd)

In this table, the following conventions are used:

• Rs0, Gs0, Bs0 and As0 represent the first source color R, G, B, and A components, respectively.

• Rd, Gd, Bd and Ad represent the R, G, B, and A components of the destination color. That is, the color currently in the corresponding color attachment for this fragment/sample.

• Sr, Sg, Sb and Sa represent the source blend factor R, G, B, and A components, respectively.

• Dr, Dg, Db and Da represent the destination blend factor R, G, B, and A components, respectively.

The blending operation produces a new set of values R, G, B and A, which are written to the framebuffer attachment. If blending is not enabled for this attachment, then R, G, B and A are assigned Rs0, Gs0, Bs0 and As0, respectively.

If the color attachment is fixed-point, the components of the source and destination values and blend factors are each clamped to [0,1] or [-1,1] respectively for an unsigned normalized or signed normalized color attachment prior to evaluating the blend operations. If the color attachment is floating-point, no clamping occurs.

If the numeric format of a framebuffer attachment uses sRGB encoding, the R, G, and B destination color values (after conversion from fixed-point to floating-point) are considered to be encoded for the sRGB color space and hence are linearized prior to their use in blending. Each R, G, and B component is converted from nonlinear to linear as described in the “sRGB EOTF” section of the Khronos Data Format Specification. If the format is not sRGB, no linearization is performed.

If the numeric format of a framebuffer attachment uses sRGB encoding, then the final R, G and B values are converted into the nonlinear sRGB representation before being written to the framebuffer attachment as described in the “sRGB EOTF -1” section of the Khronos Data Format Specification.

If the framebuffer color attachment numeric format is not sRGB encoded then the resulting cs values for R, G and B are unmodified. The value of A is never sRGB encoded. That is, the alpha component is always stored in memory as linear.

If the framebuffer color attachment is VK_ATTACHMENT_UNUSED, no writes are performed through that attachment. Framebuffer color attachments greater than or equal to VkSubpassDescription::colorAttachmentCount perform no writes.

### 26.2. Logical Operations

The application can enable a logical operation between the fragment’s color values and the existing value in the framebuffer attachment. This logical operation is applied prior to updating the framebuffer attachment. Logical operations are applied only for signed and unsigned integer and normalized integer framebuffers. Logical operations are not applied to floating-point or sRGB format color attachments.

Logical operations are controlled by the logicOpEnable and logicOp members of VkPipelineColorBlendStateCreateInfo. If logicOpEnable is VK_TRUE, then a logical operation selected by logicOp is applied between each color attachment and the fragment’s corresponding output value, and blending of all attachments is treated as if it were disabled. Any attachments using color formats for which logical operations are not supported simply pass through the color values unmodified. The logical operation is applied independently for each of the red, green, blue, and alpha components. The logicOp is selected from the following operations:

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;

The logical operations supported by Vulkan are summarized in the following table in which

• ¬ is bitwise invert,

• is bitwise and,

• is bitwise or,

• is bitwise exclusive or,

• s is the fragment’s Rs0, Gs0, Bs0 or As0 component value for the fragment output corresponding to the color attachment being updated, and

• d is the color attachment’s R, G, B or A component value:

Table 26. Logical Operations
Mode Operation

VK_LOGIC_OP_CLEAR

0

VK_LOGIC_OP_AND

s ∧ d

VK_LOGIC_OP_AND_REVERSE

s ∧ ¬ d

VK_LOGIC_OP_COPY

s

VK_LOGIC_OP_AND_INVERTED

¬ s ∧ d

VK_LOGIC_OP_NO_OP

d

VK_LOGIC_OP_XOR

s ⊕ d

VK_LOGIC_OP_OR

s ∨ d

VK_LOGIC_OP_NOR

¬ (s ∨ d)

VK_LOGIC_OP_EQUIVALENT

¬ (s ⊕ d)

VK_LOGIC_OP_INVERT

¬ d

VK_LOGIC_OP_OR_REVERSE

s ∨ ¬ d

VK_LOGIC_OP_COPY_INVERTED

¬ s

VK_LOGIC_OP_OR_INVERTED

¬ s ∨ d

VK_LOGIC_OP_NAND

¬ (s ∧ d)

VK_LOGIC_OP_SET

all 1s

The result of the logical operation is then written to the color attachment as controlled by the component write mask, described in Blend Operations.

Bits which can be set in VkPipelineColorBlendAttachmentState::colorWriteMask to determine whether the final color values R, G, B and A are written to the framebuffer attachment are:

typedef enum VkColorComponentFlagBits {
VK_COLOR_COMPONENT_R_BIT = 0x00000001,
VK_COLOR_COMPONENT_G_BIT = 0x00000002,
VK_COLOR_COMPONENT_B_BIT = 0x00000004,
VK_COLOR_COMPONENT_A_BIT = 0x00000008,
VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkColorComponentFlagBits;
• VK_COLOR_COMPONENT_R_BIT specifies that the R value is written to the color attachment for the appropriate sample. Otherwise, the value in memory is unmodified.

• VK_COLOR_COMPONENT_G_BIT specifies that the G value is written to the color attachment for the appropriate sample. Otherwise, the value in memory is unmodified.

• VK_COLOR_COMPONENT_B_BIT specifies that the B value is written to the color attachment for the appropriate sample. Otherwise, the value in memory is unmodified.

• VK_COLOR_COMPONENT_A_BIT specifies that the A value is written to the color attachment for the appropriate sample. Otherwise, the value in memory is unmodified.

The color write mask operation is applied regardless of whether blending is enabled.

typedef VkFlags VkColorComponentFlags;

VkColorComponentFlags is a bitmask type for setting a mask of zero or more VkColorComponentFlagBits.