diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 12000e605f5..3782919cbd1 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -985,6 +985,32 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, return; } + /** + * Section 7.7.4 of the Vulkan 1.3.260 spec says: + * + * If the transfer is via an image memory barrier, and an image layout + * transition is desired, then the values of oldLayout and newLayout in the + * release operation's memory barrier must be equal to values of oldLayout + * and newLayout in the acquire operation's memory barrier. Although the + * image layout transition is submitted twice, it will only be executed + * once. A layout transition specified in this way happens-after the + * release operation and happens-before the acquire operation. + * + * Because we know that we get match transition on each queue, we choose to + * only do the work on one queue type : RENDER. In the cases where we do + * transitions between COMPUTE & TRANSFER, we should have matching + * aux/fast_clear value which would trigger no work in the code below. + */ + if (!(src_queue_external || dst_queue_external) && + src_queue_family != VK_QUEUE_FAMILY_IGNORED && + dst_queue_family != VK_QUEUE_FAMILY_IGNORED && + src_queue_family != dst_queue_family) { + enum intel_engine_class src_engine = + cmd_buffer->queue_family[src_queue_family].engine_class; + if (src_engine != INTEL_ENGINE_CLASS_RENDER) + return; + } + const uint32_t plane = anv_image_aspect_to_plane(image, aspect); if (base_layer >= anv_image_aux_layers(image, aspect, base_level))