The Framebuffer

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. Advanced blending operations are performed with a precision and dynamic range no lower than the smaller of that used to represent destination components or that used to represent 16-bit floating-point values.

Blending is only defined for floating-point, UNORM, SNORM, and sRGB formats. Within those formats, the implementation may only support blending on some subset of them. Which formats support blending is indicated by VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.

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

VkPipelineColorBlendStateCreateInfoStructure specifying parameters of a newly created pipeline color blend state
VkPipelineColorBlendStateCreateFlagsBitmask of VkPipelineColorBlendStateCreateFlagBits
VkPipelineColorBlendStateCreateFlagBitsBitmask specifying additional parameters of an image
VkPipelineColorBlendAttachmentStateStructure specifying a pipeline color blend attachment state
vkCmdSetColorBlendEnableEXTSpecify the blendEnable for each attachment dynamically for a command buffer
vkCmdSetColorBlendEquationEXTSpecify the blend factors and operations dynamically for a command buffer
VkColorBlendEquationEXTStructure specifying the color blend factors and operations for an attachment
vkCmdSetColorWriteMaskEXTSpecify the color write masks for each attachment dynamically for a command buffer

Blend Factors

VkBlendFactorFramebuffer blending factors
vkCmdSetBlendConstantsSet the values of blend constants

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.

Color outputs can be 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 value of the second input is undefined:.

Blend Operations

VkBlendOpFramebuffer blending operations

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 numeric format of a framebuffer color attachment 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. Writes are not performed to framebuffer color attachments greater than or equal to the VkSubpassDescription::colorAttachmentCount or VkSubpassDescription2::colorAttachmentCount value.

Advanced Blend Operations

The advanced blend operations are those listed in tables f/X/Y/Z Advanced Blend Operations, Hue-Saturation-Luminosity Advanced Blend Operations, and Additional RGB Blend Operations.

VkPipelineColorBlendAdvancedStateCreateInfoEXTStructure specifying parameters that affect advanced blend operations
vkCmdSetColorBlendAdvancedEXTSpecify the advanced color blend state dynamically for a command buffer
VkColorBlendAdvancedEXTStructure specifying the advanced blend operation parameters for an attachment

When using one of the operations in table f/X/Y/Z Advanced Blend Operations or Hue-Saturation-Luminosity Advanced Blend Operations, blending is performed according to the following equations:

R=f(R_s,R_d)p_0(A_s,A_d)+YR_sp_1(A_s,A_d)+ZR_dp_2(A_s,A_d) G=f(G_s,G_d)p_0(A_s,A_d)+YG_sp_1(A_s,A_d)+ZG_dp_2(A_s,A_d) B=f(B_s,B_d)p_0(A_s,A_d)+YB_sp_1(A_s,A_d)+ZB_dp_2(A_s,A_d) A=Xp_0(A_s,A_d)+Yp_1(A_s,A_d)+Zp_2(A_s,A_d)\begin{aligned} R & = & f(R\_s',R\_d')*p\_0(A\_s,A\_d) & + & Y*R\_s'*p\_1(A\_s,A\_d) & + & Z*R\_d'*p\_2(A\_s,A\_d) \\\ G & = & f(G\_s',G\_d')*p\_0(A\_s,A\_d) & + & Y*G\_s'*p\_1(A\_s,A\_d) & + & Z*G\_d'*p\_2(A\_s,A\_d) \\\ B & = & f(B\_s',B\_d')*p\_0(A\_s,A\_d) & + & Y*B\_s'*p\_1(A\_s,A\_d) & + & Z*B\_d'*p\_2(A\_s,A\_d) \\\ A & = & X*p\_0(A\_s,A\_d) & + & Y*p\_1(A\_s,A\_d) & + & Z*p\_2(A\_s,A\_d) \end{aligned}

where the function f and terms X, Y, and Z are specified in the table. The R, G, and B components of the source color used for blending are derived according to srcPremultiplied. If srcPremultiplied is set to VK_TRUE, the fragment color components are considered to have been premultiplied by the A component prior to blending. The base source color (Rs',Gs',Bs') is obtained by dividing through by the A component:

(R_s,G_s,B_s)={(0,0,0)A_s=0 (R_sA_s,G_sA_s,B_sA_s)otherwise\begin{aligned} (R\_s', G\_s', B\_s') & = \begin{cases} (0, 0, 0) & A\_s = 0 \\\ (\frac{R\_s}{A\_s}, \frac{G\_s}{A\_s}, \frac{B\_s}{A\_s}) & \text{otherwise} \end{cases} \end{aligned}

If srcPremultiplied is VK_FALSE, the fragment color components are used as the base color:

(R_s,G_s,B_s)=(R_s,G_s,B_s)\begin{aligned} (R\_s', G\_s', B\_s') & = (R\_s, G\_s, B\_s) \end{aligned}

The R, G, and B components of the destination color used for blending are derived according to dstPremultiplied. If dstPremultiplied is set to VK_TRUE, the destination components are considered to have been premultiplied by the A component prior to blending. The base destination color (Rd',Gd',Bd') is obtained by dividing through by the A component:

(R_d,G_d,B_d)={(0,0,0)A_d=0 (R_dA_d,G_dA_d,B_dA_d)otherwise\begin{aligned} (R\_d', G\_d', B\_d') & = \begin{cases} (0, 0, 0) & A\_d = 0 \\\ (\frac{R\_d}{A\_d}, \frac{G\_d}{A\_d}, \frac{B\_d}{A\_d}) & \text{otherwise} \end{cases} \end{aligned}

If dstPremultiplied is VK_FALSE, the destination color components are used as the base color:

(R_d,G_d,B_d)=(R_d,G_d,B_d)\begin{aligned} (R\_d', G\_d', B\_d') & = (R\_d, G\_d, B\_d) \end{aligned}

When blending using advanced blend operations, we expect that the R, G, and B components of premultiplied source and destination color inputs be stored as the product of non-premultiplied R, G, and B component values and the A component of the color. If any R, G, or B component of a premultiplied input color is non-zero and the A component is zero, the color is considered ill-formed, and the corresponding component of the blend result is undefined:.

All of the advanced blend operation formulas in this chapter compute the result as a premultiplied color. If dstPremultiplied is VK_FALSE, that result color’s R, G, and B components are divided by the A component before being written to the framebuffer. If any R, G, or B component of the color is non-zero and the A component is zero, the result is considered ill-formed, and the corresponding component of the blend result is undefined:. If all components are zero, that value is unchanged.

If the A component of any input or result color is less than zero, the color is considered ill-formed, and all components of the blend result are undefined:.

VkBlendOverlapEXTEnumerant specifying the blend overlap parameter
Table 42. f/X/Y/Z Advanced Blend Operations
ModeBlend Coefficients

VK_BLEND_OP_ZERO_EXT

VK_BLEND_OP_SRC_EXT

VK_BLEND_OP_DST_EXT

VK_BLEND_OP_SRC_OVER_EXT

VK_BLEND_OP_DST_OVER_EXT

VK_BLEND_OP_SRC_IN_EXT

VK_BLEND_OP_DST_IN_EXT

VK_BLEND_OP_SRC_OUT_EXT

VK_BLEND_OP_DST_OUT_EXT

VK_BLEND_OP_SRC_ATOP_EXT

VK_BLEND_OP_DST_ATOP_EXT

VK_BLEND_OP_XOR_EXT

VK_BLEND_OP_MULTIPLY_EXT

VK_BLEND_OP_SCREEN_EXT

VK_BLEND_OP_OVERLAY_EXT

VK_BLEND_OP_DARKEN_EXT

VK_BLEND_OP_LIGHTEN_EXT

VK_BLEND_OP_COLORDODGE_EXT

VK_BLEND_OP_COLORBURN_EXT

VK_BLEND_OP_HARDLIGHT_EXT

VK_BLEND_OP_SOFTLIGHT_EXT

VK_BLEND_OP_DIFFERENCE_EXT

VK_BLEND_OP_EXCLUSION_EXT

VK_BLEND_OP_INVERT_EXT

VK_BLEND_OP_INVERT_RGB_EXT

VK_BLEND_OP_LINEARDODGE_EXT

VK_BLEND_OP_LINEARBURN_EXT

VK_BLEND_OP_VIVIDLIGHT_EXT

VK_BLEND_OP_LINEARLIGHT_EXT

VK_BLEND_OP_PINLIGHT_EXT

VK_BLEND_OP_HARDMIX_EXT

When using one of the HSL blend operations in table Hue-Saturation-Luminosity Advanced Blend Operations as the blend operation, the RGB color components produced by the function f are effectively obtained by converting both the non-premultiplied source and destination colors to the HSL (hue, saturation, luminosity) color space, generating a new HSL color by selecting H, S, and L components from the source or destination according to the blend operation, and then converting the result back to RGB. In the equations below, a blended RGB color is produced according to the following pseudocode:

  float minv3(vec3 c) {
    return min(min(c.r, c.g), c.b);
  }
  float maxv3(vec3 c) {
    return max(max(c.r, c.g), c.b);
  }
  float lumv3(vec3 c) {
    return dot(c, vec3(0.30, 0.59, 0.11));
  }
  float satv3(vec3 c) {
    return maxv3(c) - minv3(c);
  }

  // If any color components are outside [0,1], adjust the color to
  // get the components in range.
  vec3 ClipColor(vec3 color) {
    float lum = lumv3(color);
    float mincol = minv3(color);
    float maxcol = maxv3(color);
    if (mincol < 0.0) {
      color = lum + ((color-lum)*lum) / (lum-mincol);
    }
    if (maxcol > 1.0) {
      color = lum + ((color-lum)*(1-lum)) / (maxcol-lum);
    }
    return color;
  }

  // Take the base RGB color <cbase> and override its luminosity
  // with that of the RGB color <clum>.
  vec3 SetLum(vec3 cbase, vec3 clum) {
    float lbase = lumv3(cbase);
    float llum = lumv3(clum);
    float ldiff = llum - lbase;
    vec3 color = cbase + vec3(ldiff);
    return ClipColor(color);
  }

  // Take the base RGB color <cbase> and override its saturation with
  // that of the RGB color <csat>.  The override the luminosity of the
  // result with that of the RGB color <clum>.
  vec3 SetLumSat(vec3 cbase, vec3 csat, vec3 clum)
  {
    float minbase = minv3(cbase);
    float sbase = satv3(cbase);
    float ssat = satv3(csat);
    vec3 color;
    if (sbase > 0) {
      // Equivalent (modulo rounding errors) to setting the
      // smallest (R,G,B) component to 0, the largest to <ssat>,
      // and interpolating the "middle" component based on its
      // original value relative to the smallest/largest.
      color = (cbase - minbase) * ssat / sbase;
    } else {
      color = vec3(0.0);
    }
    return SetLum(color, clum);
  }
Table 43. Hue-Saturation-Luminosity Advanced Blend Operations
ModeResult

VK_BLEND_OP_HSL_HUE_EXT

VK_BLEND_OP_HSL_SATURATION_EXT

VK_BLEND_OP_HSL_COLOR_EXT

VK_BLEND_OP_HSL_LUMINOSITY_EXT

When using one of the operations in table Additional RGB Blend Operations as the blend operation, the source and destination colors used by these blending operations are interpreted according to srcPremultiplied and dstPremultiplied. The blending operations below are evaluated where the RGB source and destination color components are both considered to have been premultiplied by the corresponding A component.

(R_s,G_s,B_s)={(R_s,G_s,B_s)if srcPremultiplied is VK_TRUE (R_sA_s,G_sA_s,B_sA_s)if srcPremultiplied is VK_FALSE (R_d,G_d,B_d)={(R_d,G_d,B_d)if dstPremultiplied is VK_TRUE (R_dA_d,G_dA_d,B_dA_d)if dstPremultiplied is VK_FALSE\begin{aligned} (R\_s', G\_s', B\_s') & = \begin{cases} (R\_s, G\_s, B\_s) & \text{if srcPremultiplied is VK\\\_TRUE} \\\ (R\_sA\_s, G\_sA\_s, B\_sA\_s) & \text{if srcPremultiplied is VK\\\_FALSE} \end{cases} \\\ (R\_d', G\_d', B\_d') & = \begin{cases} (R\_d, G\_d, B\_d) & \text{if dstPremultiplied is VK\\\_TRUE} \\\ (R\_dA\_d, G\_dA\_d, B\_dA\_d) & \text{if dstPremultiplied is VK\\\_FALSE} \end{cases} \end{aligned}
Table 44. Additional RGB Blend Operations
ModeResult

VK_BLEND_OP_PLUS_EXT

VK_BLEND_OP_PLUS_CLAMPED_EXT

VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT

VK_BLEND_OP_PLUS_DARKER_EXT

VK_BLEND_OP_MINUS_EXT

VK_BLEND_OP_MINUS_CLAMPED_EXT

VK_BLEND_OP_CONTRAST_EXT

VK_BLEND_OP_INVERT_OVG_EXT

VK_BLEND_OP_RED_EXT

VK_BLEND_OP_GREEN_EXT

VK_BLEND_OP_BLUE_EXT

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.

VkLogicOpFramebuffer logical operations
vkCmdSetLogicOpEnableEXTSpecify dynamically whether logical operations are enabled for a command buffer
vkCmdSetLogicOpEXTSelect which logical operation to apply for blend state dynamically for a command buffer

Color Write Mask

VkColorComponentFlagBitsBitmask controlling which components are written to the framebuffer
VkColorComponentFlagsBitmask of VkColorComponentFlagBits

Color Write Enable

VkPipelineColorWriteCreateInfoEXTStructure specifying color write state of a newly created pipeline
vkCmdSetColorWriteEnableEXTEnable or disable writes to a color attachment dynamically for a command buffer

Framebuffer Query Instructions

vkGetFramebufferTilePropertiesQCOMGet tile properties from the attachments in framebuffer