// Copyright 2015-2023 The Khronos Group Inc.
//
// SPDX-License-Identifier: CC-BY-4.0

[[framebuffer]]
= The Framebuffer


[[framebuffer-blending]]
== 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 [eq]#(x~f~,y~f~)# 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
<<framebuffer-blendoperations,blend operation>>, quadruplets of source and
destination weighting factors determined by the <<framebuffer-blendfactors,
blend factors>>, and a <<framebuffer-blendconstants,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 <<fundamentals-fixedfpconv,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.
ifdef::VK_EXT_blend_operation_advanced[]
<<framebuffer-blend-advanced,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.
endif::VK_EXT_blend_operation_advanced[]

[NOTE]
.Note
====
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
ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.
====

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

[open,refpage='VkPipelineColorBlendStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline color blend state',type='structs']
--
The sname:VkPipelineColorBlendStateCreateInfo structure is defined as:

include::{generated}/api/structs/VkPipelineColorBlendStateCreateInfo.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
ifndef::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
  * pname:flags is reserved for future use.
endif::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
ifdef::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
  * pname:flags is a bitmask of
    elink:VkPipelineColorBlendStateCreateFlagBits specifying additional
    color blending information.
endif::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
  * pname:logicOpEnable controls whether to apply <<framebuffer-logicop,
    Logical Operations>>.
  * pname:logicOp selects which logical operation to apply.
  * pname:attachmentCount is the number of
    slink:VkPipelineColorBlendAttachmentState elements in
    pname:pAttachments.
ifdef::VK_EXT_extended_dynamic_state3[]
    It is ignored if the pipeline is created with
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, and
    ename:VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT dynamic states set, and
    either ename:VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT set or
    <<features-advancedBlendCoherentOperations,advancedBlendCoherentOperations>>
    is not enabled on the device.
endif::VK_EXT_extended_dynamic_state3[]
  * pname:pAttachments is a pointer to an array of
    slink:VkPipelineColorBlendAttachmentState structures defining blend
    state for each color attachment.
ifdef::VK_EXT_extended_dynamic_state3[]
    It is ignored if the pipeline is created with
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, and
    ename:VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT dynamic states set, and
    either ename:VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT set or
    <<features-advancedBlendCoherentOperations,advancedBlendCoherentOperations>>
    is not enabled on the device.
endif::VK_EXT_extended_dynamic_state3[]
  * pname:blendConstants is a pointer to 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 <<framebuffer-blendfactors,blend factor>>.

.Valid Usage
****
  * [[VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605]]
    If the <<features-independentBlend, pname:independentBlend>> feature is
    not enabled, all elements of pname:pAttachments must: be identical
  * [[VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00606]]
    If the <<features-logicOp, pname:logicOp>> feature is not enabled,
    pname:logicOpEnable must: be ename:VK_FALSE
  * [[VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607]]
    If pname:logicOpEnable is ename:VK_TRUE, pname:logicOp must: be a valid
    elink:VkLogicOp value
ifdef::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
  * [[VUID-VkPipelineColorBlendStateCreateInfo-rasterizationOrderColorAttachmentAccess-06465]]
    If the <<features-rasterizationOrderColorAttachmentAccess,
    pname:rasterizationOrderColorAttachmentAccess>> feature is not enabled,
    pname:flags must: not include
    ename:VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT
endif::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
  * [[VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-07353]]
    If pname:attachmentCount is not `0`
ifdef::VK_EXT_extended_dynamic_state3[]
    , and any of ename:VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT,
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, or
    ename:VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT are not set,
endif::VK_EXT_extended_dynamic_state3[]
    pname:pAttachments must: be a valid pointer to an array of
    pname:attachmentCount valid slink:VkPipelineColorBlendAttachmentState
    structures
****

include::{generated}/validity/structs/VkPipelineColorBlendStateCreateInfo.adoc[]
--

[open,refpage='VkPipelineColorBlendStateCreateFlags',desc='Bitmask of VkPipelineColorBlendStateCreateFlagBits',type='flags']
--
include::{generated}/api/flags/VkPipelineColorBlendStateCreateFlags.adoc[]

ifndef::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
tname:VkPipelineColorBlendStateCreateFlags is a bitmask type for setting a
mask, but is currently reserved for future use.
endif::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
ifdef::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
tname:VkPipelineColorBlendStateCreateFlags is a bitmask type for setting a
mask of zero or more elink:VkPipelineColorBlendStateCreateFlagBits.
endif::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
--

ifdef::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]
[open,refpage='VkPipelineColorBlendStateCreateFlagBits',desc='Bitmask specifying additional parameters of an image',type='enums']
--
Bits which can: be set in the
slink:VkPipelineColorBlendStateCreateInfo::pname:flags parameter are:

include::{generated}/api/enums/VkPipelineColorBlendStateCreateFlagBits.adoc[]

  * ename:VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT
    indicates that access to color and input attachments will have implicit
    framebuffer-local memory dependencies, allowing applications to express
    custom blending operations in a fragment shader.

When
ename:VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT
is included in a pipeline, it forms a framebuffer-local memory dependency
for each fragment generated by draw commands for that pipeline with the
following scopes:

  * The first <<synchronization-dependencies-scopes, synchronization scope>>
    includes the ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
    pipeline stage executed by all previous fragments (as defined by
    <<drawing-primitive-order, primitive order>>) in the corresponding
    <<synchronization-framebuffer-regions, framebuffer regions>> including
    those generated by the same draw command.
  * The second <<synchronization-dependencies-scopes, synchronization
    scope>> includes the ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
    pipeline stage executed by the generated fragment.
  * The first <<synchronization-dependencies-access-scopes, access scope>>
    includes all writes to color attachments.
  * The second <<synchronization-dependencies-access-scopes, access scope>>
    includes all reads from input attachments.
--
endif::VK_EXT_rasterization_order_attachment_access,VK_ARM_rasterization_order_attachment_access[]

[open,refpage='VkPipelineColorBlendAttachmentState',desc='Structure specifying a pipeline color blend attachment state',type='structs']
--
The sname:VkPipelineColorBlendAttachmentState structure is defined as:

include::{generated}/api/structs/VkPipelineColorBlendAttachmentState.adoc[]

  * pname: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.
  * pname:srcColorBlendFactor selects which blend factor is used to
    determine the source factors [eq]#(S~r~,S~g~,S~b~)#.
  * pname:dstColorBlendFactor selects which blend factor is used to
    determine the destination factors [eq]#(D~r~,D~g~,D~b~)#.
  * pname:colorBlendOp selects which blend operation is used to calculate
    the RGB values to write to the color attachment.
  * pname:srcAlphaBlendFactor selects which blend factor is used to
    determine the source factor [eq]#S~a~#.
  * pname:dstAlphaBlendFactor selects which blend factor is used to
    determine the destination factor [eq]#D~a~#.
  * pname:alphaBlendOp selects which blend operation is used to calculate
    the alpha values to write to the color attachment.
  * pname:colorWriteMask is a bitmask of elink:VkColorComponentFlagBits
    specifying which of the R, G, B, and/or A components are enabled for
    writing, as described for the <<framebuffer-color-write-mask,Color Write
    Mask>>.

.Valid Usage
****
  * [[VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-00608]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:srcColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
  * [[VUID-VkPipelineColorBlendAttachmentState-dstColorBlendFactor-00609]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:dstColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
  * [[VUID-VkPipelineColorBlendAttachmentState-srcAlphaBlendFactor-00610]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:srcAlphaBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
  * [[VUID-VkPipelineColorBlendAttachmentState-dstAlphaBlendFactor-00611]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:dstAlphaBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
ifdef::VK_EXT_blend_operation_advanced[]
  * [[VUID-VkPipelineColorBlendAttachmentState-colorBlendOp-01406]]
    If either of pname:colorBlendOp or pname:alphaBlendOp is an
    <<framebuffer-blend-advanced,advanced blend operation>>, then
    pname:colorBlendOp must: equal pname:alphaBlendOp
  * [[VUID-VkPipelineColorBlendAttachmentState-advancedBlendIndependentBlend-01407]]
    If
    slink:VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT::pname:advancedBlendIndependentBlend
    is ename:VK_FALSE and pname:colorBlendOp is an
    <<framebuffer-blend-advanced,advanced blend operation>>, then
    pname:colorBlendOp must: be the same for all attachments
  * [[VUID-VkPipelineColorBlendAttachmentState-advancedBlendIndependentBlend-01408]]
    If
    slink:VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT::pname:advancedBlendIndependentBlend
    is ename:VK_FALSE and pname:alphaBlendOp is an
    <<framebuffer-blend-advanced,advanced blend operation>>, then
    pname:alphaBlendOp must: be the same for all attachments
  * [[VUID-VkPipelineColorBlendAttachmentState-advancedBlendAllOperations-01409]]
    If
    slink:VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT::pname:advancedBlendAllOperations
    is ename:VK_FALSE, then pname:colorBlendOp must: not be
    ename:VK_BLEND_OP_ZERO_EXT, ename:VK_BLEND_OP_SRC_EXT,
    ename:VK_BLEND_OP_DST_EXT, ename:VK_BLEND_OP_SRC_OVER_EXT,
    ename:VK_BLEND_OP_DST_OVER_EXT, ename:VK_BLEND_OP_SRC_IN_EXT,
    ename:VK_BLEND_OP_DST_IN_EXT, ename:VK_BLEND_OP_SRC_OUT_EXT,
    ename:VK_BLEND_OP_DST_OUT_EXT, ename:VK_BLEND_OP_SRC_ATOP_EXT,
    ename:VK_BLEND_OP_DST_ATOP_EXT, ename:VK_BLEND_OP_XOR_EXT,
    ename:VK_BLEND_OP_INVERT_EXT, ename:VK_BLEND_OP_INVERT_RGB_EXT,
    ename:VK_BLEND_OP_LINEARDODGE_EXT, ename:VK_BLEND_OP_LINEARBURN_EXT,
    ename:VK_BLEND_OP_VIVIDLIGHT_EXT, ename:VK_BLEND_OP_LINEARLIGHT_EXT,
    ename:VK_BLEND_OP_PINLIGHT_EXT, ename:VK_BLEND_OP_HARDMIX_EXT,
    ename:VK_BLEND_OP_PLUS_EXT, ename:VK_BLEND_OP_PLUS_CLAMPED_EXT,
    ename:VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT,
    ename:VK_BLEND_OP_PLUS_DARKER_EXT, ename:VK_BLEND_OP_MINUS_EXT,
    ename:VK_BLEND_OP_MINUS_CLAMPED_EXT, ename:VK_BLEND_OP_CONTRAST_EXT,
    ename:VK_BLEND_OP_INVERT_OVG_EXT, ename:VK_BLEND_OP_RED_EXT,
    ename:VK_BLEND_OP_GREEN_EXT, or ename:VK_BLEND_OP_BLUE_EXT
  * [[VUID-VkPipelineColorBlendAttachmentState-colorBlendOp-01410]]
    If pname:colorBlendOp or pname:alphaBlendOp is an
    <<framebuffer-blend-advanced,advanced blend operation>>, then
    pname:colorAttachmentCount of the subpass this pipeline is compiled
    against must: be less than or equal to
    slink:VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT::pname:advancedBlendMaxColorAttachments
endif::VK_EXT_blend_operation_advanced[]
ifdef::VK_KHR_portability_subset[]
  * [[VUID-VkPipelineColorBlendAttachmentState-constantAlphaColorBlendFactors-04454]]
    If the `apiext:VK_KHR_portability_subset` extension is enabled, and
    slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:constantAlphaColorBlendFactors
    is ename:VK_FALSE, pname:srcColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_CONSTANT_ALPHA or
    ename:VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
  * [[VUID-VkPipelineColorBlendAttachmentState-constantAlphaColorBlendFactors-04455]]
    If the `apiext:VK_KHR_portability_subset` extension is enabled, and
    slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:constantAlphaColorBlendFactors
    is ename:VK_FALSE, pname:dstColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_CONSTANT_ALPHA or
    ename:VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
endif::VK_KHR_portability_subset[]
****

include::{generated}/validity/structs/VkPipelineColorBlendAttachmentState.adoc[]
--

ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[]

[open,refpage='vkCmdSetColorBlendEnableEXT',desc='Specify the pname:blendEnable for each attachment dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> pname:blendEnable, call:

include::{generated}/api/protos/vkCmdSetColorBlendEnableEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:firstAttachment the first color attachment the color blending
    enable applies.
  * pname:attachmentCount the number of color blending enables in the
    pname:pColorBlendEnables array.
  * pname:pColorBlendEnables an array of booleans to indicate whether color
    blending is enabled for the corresponding attachment.

This command sets the color blending enable of the specified color
attachments for subsequent drawing commands
ifdef::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or]
ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.]
endif::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[]
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
endif::VK_EXT_extended_dynamic_state3[]
Otherwise, this state is specified by the
slink:VkPipelineColorBlendAttachmentState::pname:blendEnable values used to
create the currently active pipeline.

:refpage: vkCmdSetColorBlendEnableEXT
:requiredfeature: extendedDynamicState3ColorBlendEnable

.Valid Usage
****
include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[]
****

include::{generated}/validity/protos/vkCmdSetColorBlendEnableEXT.adoc[]
--

[open,refpage='vkCmdSetColorBlendEquationEXT',desc='Specify the blend factors and operations dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> color blend factors and
operations, call:

include::{generated}/api/protos/vkCmdSetColorBlendEquationEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:firstAttachment the first color attachment the color blend factors
    and operations apply to.
  * pname:attachmentCount the number of slink:VkColorBlendEquationEXT
    elements in the pname:pColorBlendEquations array.
  * pname:pColorBlendEquations an array of slink:VkColorBlendEquationEXT
    structs that specify the color blend factors and operations for the
    corresponding attachments.

This command sets the color blending factors and operations of the specified
attachments for subsequent drawing commands
ifdef::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or]
ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.]
endif::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[]
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
endif::VK_EXT_extended_dynamic_state3[]
Otherwise, this state is specified by the
slink:VkPipelineColorBlendAttachmentState::pname:srcColorBlendFactor,
slink:VkPipelineColorBlendAttachmentState::pname:dstColorBlendFactor,
slink:VkPipelineColorBlendAttachmentState::pname:colorBlendOp,
slink:VkPipelineColorBlendAttachmentState::pname:srcAlphaBlendFactor,
slink:VkPipelineColorBlendAttachmentState::pname:dstAlphaBlendFactor, and
slink:VkPipelineColorBlendAttachmentState::pname:alphaBlendOp values used to
create the currently active pipeline.

:refpage: vkCmdSetColorBlendEquationEXT
:requiredfeature: extendedDynamicState3ColorBlendEquation

.Valid Usage
****
include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[]
****

include::{generated}/validity/protos/vkCmdSetColorBlendEquationEXT.adoc[]
--

[open,refpage='VkColorBlendEquationEXT',desc='Structure specifying the color blend factors and operations for an attachment',type='structs']
--
The sname:VkColorBlendEquationEXT structure is defined as:

include::{generated}/api/structs/VkColorBlendEquationEXT.adoc[]

  * pname:srcColorBlendFactor selects which blend factor is used to
    determine the source factors [eq]#(S~r~,S~g~,S~b~)#.
  * pname:dstColorBlendFactor selects which blend factor is used to
    determine the destination factors [eq]#(D~r~,D~g~,D~b~)#.
  * pname:colorBlendOp selects which blend operation is used to calculate
    the RGB values to write to the color attachment.
  * pname:srcAlphaBlendFactor selects which blend factor is used to
    determine the source factor [eq]#S~a~#.
  * pname:dstAlphaBlendFactor selects which blend factor is used to
    determine the destination factor [eq]#D~a~#.
  * pname:alphaBlendOp selects which blend operation is use to calculate the
    alpha values to write to the color attachment.

.Valid Usage
****
  * [[VUID-VkColorBlendEquationEXT-dualSrcBlend-07357]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:srcColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
  * [[VUID-VkColorBlendEquationEXT-dualSrcBlend-07358]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:dstColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
  * [[VUID-VkColorBlendEquationEXT-dualSrcBlend-07359]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:srcAlphaBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
  * [[VUID-VkColorBlendEquationEXT-dualSrcBlend-07360]]
    If the <<features-dualSrcBlend, pname:dualSrcBlend>> feature is not
    enabled, pname:dstAlphaBlendFactor must: not be
    ename:VK_BLEND_FACTOR_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
    ename:VK_BLEND_FACTOR_SRC1_ALPHA, or
    ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
ifdef::VK_EXT_blend_operation_advanced[]
  * [[VUID-VkColorBlendEquationEXT-colorBlendOp-07361]]
    pname:colorBlendOp and pname:alphaBlendOp must: not be
    ename:VK_BLEND_OP_ZERO_EXT, ename:VK_BLEND_OP_SRC_EXT,
    ename:VK_BLEND_OP_DST_EXT, ename:VK_BLEND_OP_SRC_OVER_EXT,
    ename:VK_BLEND_OP_DST_OVER_EXT, ename:VK_BLEND_OP_SRC_IN_EXT,
    ename:VK_BLEND_OP_DST_IN_EXT, ename:VK_BLEND_OP_SRC_OUT_EXT,
    ename:VK_BLEND_OP_DST_OUT_EXT, ename:VK_BLEND_OP_SRC_ATOP_EXT,
    ename:VK_BLEND_OP_DST_ATOP_EXT, ename:VK_BLEND_OP_XOR_EXT,
    ename:VK_BLEND_OP_MULTIPLY_EXT, ename:VK_BLEND_OP_SCREEN_EXT,
    ename:VK_BLEND_OP_OVERLAY_EXT, ename:VK_BLEND_OP_DARKEN_EXT,
    ename:VK_BLEND_OP_LIGHTEN_EXT, ename:VK_BLEND_OP_COLORDODGE_EXT,
    ename:VK_BLEND_OP_COLORBURN_EXT, ename:VK_BLEND_OP_HARDLIGHT_EXT,
    ename:VK_BLEND_OP_SOFTLIGHT_EXT, ename:VK_BLEND_OP_DIFFERENCE_EXT,
    ename:VK_BLEND_OP_EXCLUSION_EXT, ename:VK_BLEND_OP_INVERT_EXT,
    ename:VK_BLEND_OP_INVERT_RGB_EXT, ename:VK_BLEND_OP_LINEARDODGE_EXT,
    ename:VK_BLEND_OP_LINEARBURN_EXT, ename:VK_BLEND_OP_VIVIDLIGHT_EXT,
    ename:VK_BLEND_OP_LINEARLIGHT_EXT, ename:VK_BLEND_OP_PINLIGHT_EXT,
    ename:VK_BLEND_OP_HARDMIX_EXT, ename:VK_BLEND_OP_HSL_HUE_EXT,
    ename:VK_BLEND_OP_HSL_SATURATION_EXT, ename:VK_BLEND_OP_HSL_COLOR_EXT,
    ename:VK_BLEND_OP_HSL_LUMINOSITY_EXT, ename:VK_BLEND_OP_PLUS_EXT,
    ename:VK_BLEND_OP_PLUS_CLAMPED_EXT,
    ename:VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT,
    ename:VK_BLEND_OP_PLUS_DARKER_EXT, ename:VK_BLEND_OP_MINUS_EXT,
    ename:VK_BLEND_OP_MINUS_CLAMPED_EXT, ename:VK_BLEND_OP_CONTRAST_EXT,
    ename:VK_BLEND_OP_INVERT_OVG_EXT, ename:VK_BLEND_OP_RED_EXT,
    ename:VK_BLEND_OP_GREEN_EXT, or ename:VK_BLEND_OP_BLUE_EXT
endif::VK_EXT_blend_operation_advanced[]
ifdef::VK_KHR_portability_subset[]
  * [[VUID-VkColorBlendEquationEXT-constantAlphaColorBlendFactors-07362]]
    If the `apiext:VK_KHR_portability_subset` extension is enabled, and
    slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:constantAlphaColorBlendFactors
    is ename:VK_FALSE, pname:srcColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_CONSTANT_ALPHA or
    ename:VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
  * [[VUID-VkColorBlendEquationEXT-constantAlphaColorBlendFactors-07363]]
    If the `apiext:VK_KHR_portability_subset` extension is enabled, and
    slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:constantAlphaColorBlendFactors
    is ename:VK_FALSE, pname:dstColorBlendFactor must: not be
    ename:VK_BLEND_FACTOR_CONSTANT_ALPHA or
    ename:VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
endif::VK_KHR_portability_subset[]
****

include::{generated}/validity/structs/VkColorBlendEquationEXT.adoc[]
--

[open,refpage='vkCmdSetColorWriteMaskEXT',desc='Specify the color write masks for each attachment dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the color write masks, call:

include::{generated}/api/protos/vkCmdSetColorWriteMaskEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:firstAttachment the first color attachment the color write masks
    apply to.
  * pname:attachmentCount the number of tlink:VkColorComponentFlags values
    in the pname:pColorWriteMasks array.
  * pname:pColorWriteMasks an array of tlink:VkColorComponentFlags values
    that specify the color write masks of the corresponding attachments.

This command sets the color write masks of the specified attachments for
subsequent drawing commands
ifdef::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or]
ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.]
endif::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[]
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
endif::VK_EXT_extended_dynamic_state3[]
Otherwise, this state is specified by the
slink:VkPipelineColorBlendAttachmentState::pname:colorWriteMask values used
to create the currently active pipeline.

[NOTE]
.Note
====
Formats with bits that are shared between components specified by
elink:VkColorComponentFlagBits, such as
ename:VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, cannot have their channels
individually masked by this functionality; either all components that share
bits have to be enabled, or none of them.
====

:refpage: vkCmdSetColorWriteMaskEXT
:requiredfeature: extendedDynamicState3ColorWriteMask

.Valid Usage
****
include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[]
****

include::{generated}/validity/protos/vkCmdSetColorWriteMaskEXT.adoc[]
--

endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[]


[[framebuffer-blendfactors]]
=== Blend Factors

[open,refpage='VkBlendFactor',desc='Framebuffer blending factors',type='enums']
--
The source and destination color and alpha blending factors are selected
from the enum:

include::{generated}/api/enums/VkBlendFactor.adoc[]

The semantics of the enum values are described in the table below:

.Blend Factors
[width="100%",options="header",align="center",cols="59%,28%,13%"]
|====
|elink:VkBlendFactor                            | RGB Blend Factors [eq]#(S~r~,S~g~,S~b~)# or [eq]#(D~r~,D~g~,D~b~)# | Alpha Blend Factor ([eq]#S~a~# or [eq]#D~a~#)
|ename:VK_BLEND_FACTOR_ZERO                     | [eq]#(0,0,0)#                              | [eq]#0#
|ename:VK_BLEND_FACTOR_ONE                      | [eq]#(1,1,1)#                              | [eq]#1#
|ename:VK_BLEND_FACTOR_SRC_COLOR                | [eq]#(R~s0~,G~s0~,B~s0~)#                  | [eq]#A~s0~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR      | [eq]#(1-R~s0~,1-G~s0~,1-B~s0~)#            | [eq]#1-A~s0~#
|ename:VK_BLEND_FACTOR_DST_COLOR                | [eq]#(R~d~,G~d~,B~d~)#                     | [eq]#A~d~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR      | [eq]#(1-R~d~,1-G~d~,1-B~d~)#               | [eq]#1-A~d~#
|ename:VK_BLEND_FACTOR_SRC_ALPHA                | [eq]#(A~s0~,A~s0~,A~s0~)#                  | [eq]#A~s0~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA      | [eq]#(1-A~s0~,1-A~s0~,1-A~s0~)#            | [eq]#1-A~s0~#
|ename:VK_BLEND_FACTOR_DST_ALPHA                | [eq]#(A~d~,A~d~,A~d~)#                     | [eq]#A~d~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA      | [eq]#(1-A~d~,1-A~d~,1-A~d~)#               | [eq]#1-A~d~#
|ename:VK_BLEND_FACTOR_CONSTANT_COLOR           | [eq]#(R~c~,G~c~,B~c~)#                     | [eq]#A~c~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR | [eq]#(1-R~c~,1-G~c~,1-B~c~)#               | [eq]#1-A~c~#
|ename:VK_BLEND_FACTOR_CONSTANT_ALPHA           | [eq]#(A~c~,A~c~,A~c~)#                     | [eq]#A~c~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA | [eq]#(1-A~c~,1-A~c~,1-A~c~)#               | [eq]#1-A~c~#
|ename:VK_BLEND_FACTOR_SRC_ALPHA_SATURATE       | [eq]#(f,f,f)#; [eq]#f = min(A~s0~,1-A~d~)# | [eq]#1#
|ename:VK_BLEND_FACTOR_SRC1_COLOR               | [eq]#(R~s1~,G~s1~,B~s1~)#                  | [eq]#A~s1~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR     | [eq]#(1-R~s1~,1-G~s1~,1-B~s1~)#            | [eq]#1-A~s1~#
|ename:VK_BLEND_FACTOR_SRC1_ALPHA               | [eq]#(A~s1~,A~s1~,A~s1~)#                  | [eq]#A~s1~#
|ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA     | [eq]#(1-A~s1~,1-A~s1~,1-A~s1~)#            | [eq]#1-A~s1~#
|====

In this table, the following conventions are used:

  * [eq]#R~s0~,G~s0~,B~s0~# and [eq]#A~s0~# represent the first source color
    R, G, B, and A components, respectively, for the fragment output
    location corresponding to the color attachment being blended.
  * [eq]#R~s1~,G~s1~,B~s1~# and [eq]#A~s1~# 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.
  * [eq]#R~d~,G~d~,B~d~# and [eq]#A~d~# 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.
  * [eq]#R~c~,G~c~,B~c~# and [eq]#A~c~# represent the blend constant R, G,
    B, and A components, respectively.
--

[open,refpage='vkCmdSetBlendConstants',desc='Set the values of blend constants',type='protos']
--
To <<pipelines-dynamic-state, dynamically set and change>> the blend
constants, call:

include::{generated}/api/protos/vkCmdSetBlendConstants.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:blendConstants is a pointer to an array of four values specifying
    the [eq]#R~c~#, [eq]#G~c~#, [eq]#B~c~#, and [eq]#A~c~# components of the
    blend constant color used in blending, depending on the
    <<framebuffer-blendfactors,blend factor>>.

[[framebuffer-blendconstants]]
This command sets blend constants for subsequent drawing commands when
ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or]
the graphics pipeline is created with ename:VK_DYNAMIC_STATE_BLEND_CONSTANTS
set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineColorBlendStateCreateInfo::pname:blendConstants values used
to create the currently active pipeline.

include::{generated}/validity/protos/vkCmdSetBlendConstants.adoc[]
--


[[framebuffer-dsb]]
=== Dual-Source Blending

Blend factors that use the secondary color input
[eq]#(R~s1~,G~s1~,B~s1~,A~s1~)# (ename:VK_BLEND_FACTOR_SRC1_COLOR,
ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
ename:VK_BLEND_FACTOR_SRC1_ALPHA, and
ename: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 <<features-dualSrcBlend,
pname: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 pname:maxFragmentDualSrcAttachments member of
sname:VkPhysicalDeviceLimits.

Color outputs can: be bound to the first and second inputs of the blender
using the code:Index decoration, as described in
<<interfaces-fragmentoutput,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:.


[[framebuffer-blendoperations]]
=== Blend Operations

[open,refpage='VkBlendOp',desc='Framebuffer blending operations',type='enums']
--
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 elink:VkBlendOp, specifying the operations, are:

include::{generated}/api/enums/VkBlendOp.adoc[]

<<<

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

.Basic Blend Operations
[width="100%",cols="45%,30%,25%",options="header",align="center"]
|====
|elink:VkBlendOp                             | RGB Components                    | Alpha Component

|ename:VK_BLEND_OP_ADD
| [eq]#R = R~s0~ {times} S~r~ {plus} R~d~ {times} D~r~# +
  [eq]#G = G~s0~ {times} S~g~ {plus} G~d~ {times} D~g~# +
  [eq]#B = B~s0~ {times} S~b~ {plus} B~d~ {times} D~b~#
| [eq]#A = A~s0~ {times} S~a~ {plus} A~d~ {times} D~a~#

|ename:VK_BLEND_OP_SUBTRACT
| [eq]#R = R~s0~ {times} S~r~ - R~d~ {times} D~r~# +
  [eq]#G = G~s0~ {times} S~g~ - G~d~ {times} D~g~# +
  [eq]#B = B~s0~ {times} S~b~ - B~d~ {times} D~b~#
| [eq]#A = A~s0~ {times} S~a~ - A~d~ {times} D~a~#

|ename:VK_BLEND_OP_REVERSE_SUBTRACT
| [eq]#R = R~d~ {times} D~r~ - R~s0~ {times} S~r~# +
  [eq]#G = G~d~ {times} D~g~ - G~s0~ {times} S~g~# +
  [eq]#B = B~d~ {times} D~b~ - B~s0~ {times} S~b~#
| [eq]#A = A~d~ {times} D~a~ - A~s0~ {times} S~a~#

|ename:VK_BLEND_OP_MIN
| [eq]#R = min(R~s0~,R~d~)# +
  [eq]#G = min(G~s0~,G~d~)# +
  [eq]#B = min(B~s0~,B~d~)#
| [eq]#A = min(A~s0~,A~d~)#

|ename:VK_BLEND_OP_MAX
| [eq]#R = max(R~s0~,R~d~)# +
  [eq]#G = max(G~s0~,G~d~)# +
  [eq]#B = max(B~s0~,B~d~)#
| [eq]#A = max(A~s0~,A~d~)#
|====

In this table, the following conventions are used:

  * [eq]#R~s0~, G~s0~, B~s0~# and [eq]#A~s0~# represent the first source
    color R, G, B, and A components, respectively.
  * [eq]#R~d~, G~d~, B~d~# and [eq]#A~d~# 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.
  * [eq]#S~r~, S~g~, S~b~# and [eq]#S~a~# represent the source blend factor
    R, G, B, and A components, respectively.
  * [eq]#D~r~, D~g~, D~b~# and [eq]#D~a~# represent the destination blend
    factor R, G, B, and A components, respectively.

The blending operation produces a new set of values [eq]#R, G, B# and
[eq]#A#, which are written to the framebuffer attachment.
If blending is not enabled for this attachment, then [eq]#R, G, B# and
[eq]#A# are assigned [eq]#R~s0~, G~s0~, B~s0~# and [eq]#A~s0~#,
respectively.

If the color attachment is fixed-point, the components of the source and
destination values and blend factors are each clamped to [eq]#[0,1]# or
[eq]#[-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 <<formats-numericformat, 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 <<data-format,Khronos Data
Format Specification>>.
If the format is not sRGB, no linearization is performed.

If the <<formats-numericformat, 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^&#160;-1^`" section of the
Khronos Data Format Specification.

If the <<formats-numericformat, numeric format>> of a framebuffer color
attachment is not sRGB encoded then the resulting [eq]#c~s~# 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 ename:VK_ATTACHMENT_UNUSED, no writes
are performed through that attachment.
Writes are not performed to framebuffer color attachments greater than or
equal to the sname:VkSubpassDescription::pname:colorAttachmentCount
ifdef::VK_VERSION_1_2,VK_KHR_create_renderpass2[]
or sname:VkSubpassDescription2::pname:colorAttachmentCount
endif::VK_VERSION_1_2,VK_KHR_create_renderpass2[]
value.

ifdef::VK_EXT_blend_operation_advanced[]
include::{chapters}/VK_EXT_blend_operation_advanced/advanced_blend.adoc[]
endif::VK_EXT_blend_operation_advanced[]


[[framebuffer-logicop]]
== 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.

[open,refpage='VkLogicOp',desc='Framebuffer logical operations',type='enums']
--
Logical operations are controlled by the pname:logicOpEnable and
pname:logicOp members of slink:VkPipelineColorBlendStateCreateInfo.
ifdef::VK_EXT_extended_dynamic_state3[]
The pname:logicOpEnable state can also be controlled by
flink:vkCmdSetLogicOpEnableEXT if graphics pipeline is created with
ename:VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
endif::VK_EXT_extended_dynamic_state3[]
ifdef::VK_EXT_extended_dynamic_state2[]
The pname:logicOp state can also be controlled by flink:vkCmdSetLogicOpEXT
if graphics pipeline is created with ename:VK_DYNAMIC_STATE_LOGIC_OP_EXT set
in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
endif::VK_EXT_extended_dynamic_state2[]
If pname:logicOpEnable is ename:VK_TRUE, then a logical operation selected
by pname: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 pname:logicOp is selected from the following operations:

include::{generated}/api/enums/VkLogicOp.adoc[]

<<<

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

  * [eq]#{lnot}# is bitwise invert,
  * [eq]#{land}# is bitwise and,
  * [eq]#{lor}# is bitwise or,
  * [eq]#{oplus}# is bitwise exclusive or,
  * [eq]#s# is the fragment's [eq]#R~s0~, G~s0~, B~s0~# or [eq]#A~s0~#
    component value for the fragment output corresponding to the color
    attachment being updated, and
  * [eq]#d# is the color attachment's [eq]#R, G, B# or [eq]#A# component
    value:

.Logical Operations
[width="75%",options="header",align="center"]
|====
|Mode                            | Operation
|ename:VK_LOGIC_OP_CLEAR         | [eq]#0#
|ename:VK_LOGIC_OP_AND           | [eq]#s {land} d#
|ename:VK_LOGIC_OP_AND_REVERSE   | [eq]#s {land} {lnot} d#
|ename:VK_LOGIC_OP_COPY          | [eq]#s#
|ename:VK_LOGIC_OP_AND_INVERTED  | [eq]#{lnot} s {land} d#
|ename:VK_LOGIC_OP_NO_OP         | [eq]#d#
|ename:VK_LOGIC_OP_XOR           | [eq]#s {oplus} d#
|ename:VK_LOGIC_OP_OR            | [eq]#s {lor} d#
|ename:VK_LOGIC_OP_NOR           | [eq]#{lnot} (s {lor} d)#
|ename:VK_LOGIC_OP_EQUIVALENT    | [eq]#{lnot} (s {oplus} d)#
|ename:VK_LOGIC_OP_INVERT        | [eq]#{lnot} d#
|ename:VK_LOGIC_OP_OR_REVERSE    | [eq]#s {lor} {lnot} d#
|ename:VK_LOGIC_OP_COPY_INVERTED | [eq]#{lnot} s#
|ename:VK_LOGIC_OP_OR_INVERTED   | [eq]#{lnot} s {lor} d#
|ename:VK_LOGIC_OP_NAND          | [eq]#{lnot} (s {land} d)#
|ename: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
<<framebuffer-blendoperations,Blend Operations>>.
--

ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[]
[open,refpage='vkCmdSetLogicOpEnableEXT',desc='Specify dynamically whether logical operations are enabled for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> whether logical operations
are enabled, call:

include::{generated}/api/protos/vkCmdSetLogicOpEnableEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:logicOpEnable specifies whether logical operations are enabled.

This command sets whether logical operations are enabled for subsequent
drawing commands
ifdef::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or]
ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.]
endif::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state3[]
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
endif::VK_EXT_extended_dynamic_state3[]
Otherwise, this state is specified by the
slink:VkPipelineColorBlendStateCreateInfo::pname:logicOpEnable value used to
create the currently active pipeline.

:refpage: vkCmdSetLogicOpEnableEXT
:requiredfeature: extendedDynamicState3LogicOpEnable

.Valid Usage
****
include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[]
****

include::{generated}/validity/protos/vkCmdSetLogicOpEnableEXT.adoc[]
--
endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[]

ifdef::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[]
[open,refpage='vkCmdSetLogicOpEXT',desc='Select which logical operation to apply for blend state dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the logical operation to
apply for blend state, call:

include::{generated}/api/protos/vkCmdSetLogicOpEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:logicOp specifies the logical operation to apply for blend state.

This command sets the logical operation for blend state for subsequent
drawing commands
ifdef::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>, or]
ifndef::VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>.]
endif::VK_EXT_shader_object[]
ifdef::VK_EXT_extended_dynamic_state2[]
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_LOGIC_OP_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
endif::VK_EXT_extended_dynamic_state2[]
Otherwise, this state is specified by the
slink:VkPipelineColorBlendStateCreateInfo::pname:logicOp value used to
create the currently active pipeline.

:refpage: vkCmdSetLogicOpEXT
:requiredfeature: extendedDynamicState2LogicOp

.Valid Usage
****
include::{chapters}/commonvalidity/dynamic_state2_optional_feature_common.adoc[]
****

include::{generated}/validity/protos/vkCmdSetLogicOpEXT.adoc[]
--
endif::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[]


[[framebuffer-color-write-mask]]
== Color Write Mask

[open,refpage='VkColorComponentFlagBits',desc='Bitmask controlling which components are written to the framebuffer',type='enums']
--
Bits which can: be set in
slink:VkPipelineColorBlendAttachmentState::pname:colorWriteMask, determining
whether the final color values [eq]#R, G, B# and [eq]#A# are written to the
framebuffer attachment, are:

include::{generated}/api/enums/VkColorComponentFlagBits.adoc[]

  * ename:VK_COLOR_COMPONENT_R_BIT specifies that the [eq]#R# value is
    written to the color attachment for the appropriate sample.
    Otherwise, the value in memory is unmodified.
  * ename:VK_COLOR_COMPONENT_G_BIT specifies that the [eq]#G# value is
    written to the color attachment for the appropriate sample.
    Otherwise, the value in memory is unmodified.
  * ename:VK_COLOR_COMPONENT_B_BIT specifies that the [eq]#B# value is
    written to the color attachment for the appropriate sample.
    Otherwise, the value in memory is unmodified.
  * ename:VK_COLOR_COMPONENT_A_BIT specifies that the [eq]#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.

ifdef::VK_EXT_color_write_enable[]
The color write mask operation is applied only if
<<framebuffer-color-write-enable,Color Write Enable>> is enabled for the
respective attachment.
Otherwise the color write mask is ignored and writes to all components of
the attachment are disabled.
endif::VK_EXT_color_write_enable[]
--

[open,refpage='VkColorComponentFlags',desc='Bitmask of VkColorComponentFlagBits',type='flags']
--
include::{generated}/api/flags/VkColorComponentFlags.adoc[]

tname:VkColorComponentFlags is a bitmask type for setting a mask of zero or
more elink:VkColorComponentFlagBits.
--


ifdef::VK_EXT_color_write_enable[]
[[framebuffer-color-write-enable]]
== Color Write Enable

[open,refpage='VkPipelineColorWriteCreateInfoEXT',desc='Structure specifying color write state of a newly created pipeline',type='structs']
--
The sname:VkPipelineColorWriteCreateInfoEXT structure is defined as:

include::{generated}/api/structs/VkPipelineColorWriteCreateInfoEXT.adoc[]

  * pname:sType is a elink:VkStructureType value identifying this structure.
  * pname:pNext is `NULL` or a pointer to a structure extending this
    structure.
  * pname:attachmentCount is the number of basetype:VkBool32 elements in
    pname:pColorWriteEnables.
  * pname:pColorWriteEnables is a pointer to an array of per target
    attachment boolean values specifying whether color writes are enabled
    for the given attachment.

When this structure is included in the pname:pNext chain of
slink:VkPipelineColorBlendStateCreateInfo, it defines per-attachment color
write state.
If this structure is not included in the pname:pNext chain, it is equivalent
to specifying this structure with pname:attachmentCount equal to the
pname:attachmentCount member of slink:VkPipelineColorBlendStateCreateInfo,
and pname:pColorWriteEnables pointing to an array of as many ename:VK_TRUE
values.

If the <<features-colorWriteEnable, pname:colorWriteEnable>> feature is not
enabled on the device, all basetype:VkBool32 elements in the
pname:pColorWriteEnables array must: be ename:VK_TRUE.

Color Write Enable interacts with the <<framebuffer-color-write-mask,Color
Write Mask>> as follows:

  * If pname:colorWriteEnable is ename:VK_TRUE, writes to the attachment are
    determined by the pname:colorWriteMask.
  * If pname:colorWriteEnable is ename:VK_FALSE, the pname:colorWriteMask is
    ignored and writes to all components of the attachment are disabled.
    This is equivalent to specifying a pname:colorWriteMask of 0.

.Valid Usage
****
  * [[VUID-VkPipelineColorWriteCreateInfoEXT-pAttachments-04801]]
    If the <<features-colorWriteEnable, pname:colorWriteEnable>> feature is
    not enabled, all elements of pname:pColorWriteEnables must: be
    ename:VK_TRUE
  * [[VUID-VkPipelineColorWriteCreateInfoEXT-attachmentCount-07608]]
ifdef::VK_EXT_extended_dynamic_state3[]
    If the pipeline is being created with
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT,
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
    ename:VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, or
    ename:VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT dynamic states not set,
endif::VK_EXT_extended_dynamic_state3[]
    pname:attachmentCount must: be equal to the pname:attachmentCount member
    of the sname:VkPipelineColorBlendStateCreateInfo structure specified
    during pipeline creation
  * [[VUID-VkPipelineColorWriteCreateInfoEXT-attachmentCount-06655]]
    pname:attachmentCount must: be less than or equal to the
    pname:maxColorAttachments member of sname:VkPhysicalDeviceLimits
****

include::{generated}/validity/structs/VkPipelineColorWriteCreateInfoEXT.adoc[]
--

[open,refpage='vkCmdSetColorWriteEnableEXT',desc='Enable or disable writes to a color attachment dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically enable or disable>> writes to a
color attachment, call:

include::{generated}/api/protos/vkCmdSetColorWriteEnableEXT.adoc[]

  * pname:commandBuffer is the command buffer into which the command will be
    recorded.
  * pname:attachmentCount is the number of basetype:VkBool32 elements in
    pname:pColorWriteEnables.
  * pname:pColorWriteEnables is a pointer to an array of per target
    attachment boolean values specifying whether color writes are enabled
    for the given attachment.

This command sets the color write enables for subsequent drawing commands
ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or]
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineColorWriteCreateInfoEXT::pname:pColorWriteEnables values
used to create the currently active pipeline.

.Valid Usage
****
  * [[VUID-vkCmdSetColorWriteEnableEXT-None-04803]]
    The <<features-colorWriteEnable, pname:colorWriteEnable>> feature must:
    be enabled
  * [[VUID-vkCmdSetColorWriteEnableEXT-attachmentCount-06656]]
    pname:attachmentCount must: be less than or equal to the
    pname:maxColorAttachments member of sname:VkPhysicalDeviceLimits
****

include::{generated}/validity/protos/vkCmdSetColorWriteEnableEXT.adoc[]
--
endif::VK_EXT_color_write_enable[]


ifdef::VK_QCOM_tile_properties[]
[[framebuffer-queries]]
== Framebuffer Query Instructions

[open,refpage='vkGetFramebufferTilePropertiesQCOM',desc='Get tile properties from the attachments in framebuffer',type='protos']
--
To query the tile properties from the attachments in framebuffer, call:

include::{generated}/api/protos/vkGetFramebufferTilePropertiesQCOM.adoc[]

  * pname:device is a logical device associated with the framebuffer.
  * pname:framebuffer is a handle of the framebuffer to query.
  * pname:pPropertiesCount is a pointer to an integer related to the number
    of tile properties available or queried, as described below.
  * pname:pProperties is either `NULL` or a pointer to an array of
    slink:VkTilePropertiesQCOM structures.

If pname:pProperties is `NULL`, then the number of tile properties available
is returned in pname:pPropertiesCount.
Otherwise, pname:pPropertiesCount must: point to a variable set by the user
to the number of elements in the pname:pProperties array, and on return the
variable is overwritten with the number of properties actually written to
pname:pProperties.
If pname:pPropertiesCount is less than the number of tile properties
available, at most pname:pPropertiesCount structures will be written, and
ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS, to
indicate that not all the available properties were returned.

The number of tile properties available is determined by the number of
merged subpasses, and each tile property is associated with a merged
subpass.
There will be at most as many properties as there are subpasses within the
render pass.
To obtain the tile properties for a given merged subpass, the `pProperties`
array can be indexed using the `postMergeIndex` value provided in
slink:VkRenderPassSubpassFeedbackInfoEXT.

include::{generated}/validity/protos/vkGetFramebufferTilePropertiesQCOM.adoc[]
--
endif::VK_QCOM_tile_properties[]
