layers:Refactor image barrier validation
authorTobin Ehlis <tobine@google.com>
Fri, 21 Jul 2017 20:12:23 +0000 (14:12 -0600)
committerTobin Ehlis <tobine@google.com>
Mon, 24 Jul 2017 21:28:18 +0000 (15:28 -0600)
Move image barrier validation within a renderPass into its own function
in order to break up existing code a bit. Add a check to make sure
framebuffer is valid before attempting to use FB state.

layers/core_validation.cpp

index 6a66a5f..00e36a8 100644 (file)
@@ -6154,111 +6154,45 @@ static VkPipelineStageFlags ExpandPipelineStageFlags(VkPipelineStageFlags inflag
                   VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
 }
 
-// Validate VUs for Pipeline Barriers that are within a renderPass
-// Pre: cb_state->activeRenderPass must be a pointer to valid renderPass state
-static bool ValidateRenderPassPipelineBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state,
-                                               VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask,
-                                               VkDependencyFlags dependency_flags, uint32_t mem_barrier_count,
-                                               const VkMemoryBarrier *mem_barriers, uint32_t buffer_mem_barrier_count,
-                                               const VkBufferMemoryBarrier *buffer_mem_barriers, uint32_t image_mem_barrier_count,
-                                               const VkImageMemoryBarrier *image_barriers) {
-    bool skip = false;
-    auto rp_state = cb_state->activeRenderPass;
-    const auto active_subpass = cb_state->activeSubpass;
-    auto rp_handle = HandleToUint64(rp_state->renderPass);
-    if (!rp_state->hasSelfDependency[active_subpass]) {
-        skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
-                        rp_handle, __LINE__, VALIDATION_ERROR_1b800928, "CORE",
-                        "%s: Barriers cannot be set during subpass %d of renderPass 0x%" PRIx64
-                        " with no self-dependency specified. %s",
-                        funcName, active_subpass, rp_handle, validation_error_map[VALIDATION_ERROR_1b800928]);
-    } else {
-        assert(rp_state->subpass_to_dependency_index[cb_state->activeSubpass] != -1);
-        // Grab ref to current subpassDescription up-front for use below
-        const auto &sub_desc = rp_state->createInfo.pSubpasses[active_subpass];
-        const auto &sub_dep = rp_state->createInfo.pDependencies[rp_state->subpass_to_dependency_index[active_subpass]];
-        const auto &sub_src_stage_mask = ExpandPipelineStageFlags(sub_dep.srcStageMask);
-        const auto &sub_dst_stage_mask = ExpandPipelineStageFlags(sub_dep.dstStageMask);
-        if ((sub_src_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) &&
-            (src_stage_mask != (sub_src_stage_mask & src_stage_mask))) {
+// Validate image barriers within a renderPass
+static bool ValidateRenderPassImageBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state,
+                                            uint32_t active_subpass, const safe_VkSubpassDescription &sub_desc, uint64_t rp_handle,
+                                            VkAccessFlags sub_src_access_mask, VkAccessFlags sub_dst_access_mask,
+                                            uint32_t image_mem_barrier_count, const VkImageMemoryBarrier *image_barriers) {
+    bool skip = false;
+    for (uint32_t i = 0; i < image_mem_barrier_count; ++i) {
+        const auto &img_barrier = image_barriers[i];
+        const auto &img_src_access_mask = img_barrier.srcAccessMask;
+        if (img_src_access_mask != (sub_src_access_mask & img_src_access_mask)) {
             skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
-                            rp_handle, __LINE__, VALIDATION_ERROR_1b80092a, "CORE",
-                            "%s: Barrier srcStageMask(0x%X) is not a subset of VkSubpassDependency srcStageMask(0x%X) of "
+                            rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE",
+                            "%s: Barrier pImageMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency "
+                            "srcAccessMask(0x%X) of "
                             "subpass %d of renderPass 0x%" PRIx64 ". %s",
-                            funcName, src_stage_mask, sub_src_stage_mask, active_subpass, rp_handle,
-                            validation_error_map[VALIDATION_ERROR_1b80092a]);
+                            funcName, i, img_src_access_mask, sub_src_access_mask, active_subpass, rp_handle,
+                            validation_error_map[VALIDATION_ERROR_1b80092e]);
         }
-        if ((sub_dst_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) &&
-            (dst_stage_mask != (sub_dst_stage_mask & dst_stage_mask))) {
+        const auto &img_dst_access_mask = img_barrier.dstAccessMask;
+        if (img_dst_access_mask != (sub_dst_access_mask & img_dst_access_mask)) {
             skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
-                            rp_handle, __LINE__, VALIDATION_ERROR_1b80092c, "CORE",
-                            "%s: Barrier dstStageMask(0x%X) is not a subset of VkSubpassDependency dstStageMask(0x%X) of "
+                            rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE",
+                            "%s: Barrier pImageMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency "
+                            "dstAccessMask(0x%X) of "
                             "subpass %d of renderPass 0x%" PRIx64 ". %s",
-                            funcName, dst_stage_mask, sub_dst_stage_mask, active_subpass, rp_handle,
-                            validation_error_map[VALIDATION_ERROR_1b80092c]);
+                            funcName, i, img_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle,
+                            validation_error_map[VALIDATION_ERROR_1b800930]);
         }
-        if (0 != buffer_mem_barrier_count) {
-            skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
-                            rp_handle, __LINE__, VALIDATION_ERROR_1b800934, "CORE",
-                            "%s: bufferMemoryBarrierCount is non-zero (%d) for "
-                            "subpass %d of renderPass 0x%" PRIx64 ". %s",
-                            funcName, buffer_mem_barrier_count, active_subpass, rp_handle,
-                            validation_error_map[VALIDATION_ERROR_1b800934]);
-        }
-        const auto &sub_src_access_mask = sub_dep.srcAccessMask;
-        const auto &sub_dst_access_mask = sub_dep.dstAccessMask;
-        for (uint32_t i = 0; i < mem_barrier_count; ++i) {
-            const auto &mb_src_access_mask = mem_barriers[i].srcAccessMask;
-            if (mb_src_access_mask != (sub_src_access_mask & mb_src_access_mask)) {
-                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE",
-                                "%s: Barrier pMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency "
-                                "srcAccessMask(0x%X) of "
-                                "subpass %d of renderPass 0x%" PRIx64 ". %s",
-                                funcName, i, mb_src_access_mask, sub_src_access_mask, active_subpass, rp_handle,
-                                validation_error_map[VALIDATION_ERROR_1b80092e]);
-            }
-            const auto &mb_dst_access_mask = mem_barriers[i].dstAccessMask;
-            if (mb_dst_access_mask != (sub_dst_access_mask & mb_dst_access_mask)) {
-                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE",
-                                "%s: Barrier pMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency "
-                                "dstAccessMask(0x%X) of "
-                                "subpass %d of renderPass 0x%" PRIx64 ". %s",
-                                funcName, i, mb_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle,
-                                validation_error_map[VALIDATION_ERROR_1b800930]);
-            }
-        }
-        for (uint32_t i = 0; i < image_mem_barrier_count; ++i) {
-            const auto &img_barrier = image_barriers[i];
-            const auto &img_src_access_mask = img_barrier.srcAccessMask;
-            if (img_src_access_mask != (sub_src_access_mask & img_src_access_mask)) {
-                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE",
-                                "%s: Barrier pImageMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency "
-                                "srcAccessMask(0x%X) of "
-                                "subpass %d of renderPass 0x%" PRIx64 ". %s",
-                                funcName, i, img_src_access_mask, sub_src_access_mask, active_subpass, rp_handle,
-                                validation_error_map[VALIDATION_ERROR_1b80092e]);
-            }
-            const auto &img_dst_access_mask = img_barrier.dstAccessMask;
-            if (img_dst_access_mask != (sub_dst_access_mask & img_dst_access_mask)) {
-                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE",
-                                "%s: Barrier pImageMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency "
-                                "dstAccessMask(0x%X) of "
-                                "subpass %d of renderPass 0x%" PRIx64 ". %s",
-                                funcName, i, img_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle,
-                                validation_error_map[VALIDATION_ERROR_1b800930]);
-            }
-            // Verify that a framebuffer image matches barrier image
-            const auto &fb_state = GetFramebufferState(device_data, cb_state->activeFramebuffer);
+        // TODO : Secondary CBs could have null framebuffer so just skipping that case for now. Need to correctly
+        //  handle that case at ExecuteCBs time
+        const auto &fb_state = GetFramebufferState(device_data, cb_state->activeFramebuffer);
+        if (fb_state) {
             const auto img_bar_image = img_barrier.image;
             bool image_match = false;
             bool sub_image_found = false;  // Do we find a corresponding subpass description
             VkImageLayout sub_image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
             uint32_t attach_index = 0;
             uint32_t index_count = 0;
+            // Verify that a framebuffer image matches barrier image
             for (const auto &fb_attach : fb_state->attachments) {
                 if (img_bar_image == fb_attach.image) {
                     image_match = true;
@@ -6326,6 +6260,87 @@ static bool ValidateRenderPassPipelineBarriers(layer_data *device_data, const ch
                 }
             }
         }
+    }
+    return skip;
+}
+
+// Validate VUs for Pipeline Barriers that are within a renderPass
+// Pre: cb_state->activeRenderPass must be a pointer to valid renderPass state
+static bool ValidateRenderPassPipelineBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state,
+                                               VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask,
+                                               VkDependencyFlags dependency_flags, uint32_t mem_barrier_count,
+                                               const VkMemoryBarrier *mem_barriers, uint32_t buffer_mem_barrier_count,
+                                               const VkBufferMemoryBarrier *buffer_mem_barriers, uint32_t image_mem_barrier_count,
+                                               const VkImageMemoryBarrier *image_barriers) {
+    bool skip = false;
+    auto rp_state = cb_state->activeRenderPass;
+    const auto active_subpass = cb_state->activeSubpass;
+    auto rp_handle = HandleToUint64(rp_state->renderPass);
+    if (!rp_state->hasSelfDependency[active_subpass]) {
+        skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                        rp_handle, __LINE__, VALIDATION_ERROR_1b800928, "CORE",
+                        "%s: Barriers cannot be set during subpass %d of renderPass 0x%" PRIx64
+                        " with no self-dependency specified. %s",
+                        funcName, active_subpass, rp_handle, validation_error_map[VALIDATION_ERROR_1b800928]);
+    } else {
+        assert(rp_state->subpass_to_dependency_index[cb_state->activeSubpass] != -1);
+        // Grab ref to current subpassDescription up-front for use below
+        const auto &sub_desc = rp_state->createInfo.pSubpasses[active_subpass];
+        const auto &sub_dep = rp_state->createInfo.pDependencies[rp_state->subpass_to_dependency_index[active_subpass]];
+        const auto &sub_src_stage_mask = ExpandPipelineStageFlags(sub_dep.srcStageMask);
+        const auto &sub_dst_stage_mask = ExpandPipelineStageFlags(sub_dep.dstStageMask);
+        if ((sub_src_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) &&
+            (src_stage_mask != (sub_src_stage_mask & src_stage_mask))) {
+            skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                            rp_handle, __LINE__, VALIDATION_ERROR_1b80092a, "CORE",
+                            "%s: Barrier srcStageMask(0x%X) is not a subset of VkSubpassDependency srcStageMask(0x%X) of "
+                            "subpass %d of renderPass 0x%" PRIx64 ". %s",
+                            funcName, src_stage_mask, sub_src_stage_mask, active_subpass, rp_handle,
+                            validation_error_map[VALIDATION_ERROR_1b80092a]);
+        }
+        if ((sub_dst_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) &&
+            (dst_stage_mask != (sub_dst_stage_mask & dst_stage_mask))) {
+            skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                            rp_handle, __LINE__, VALIDATION_ERROR_1b80092c, "CORE",
+                            "%s: Barrier dstStageMask(0x%X) is not a subset of VkSubpassDependency dstStageMask(0x%X) of "
+                            "subpass %d of renderPass 0x%" PRIx64 ". %s",
+                            funcName, dst_stage_mask, sub_dst_stage_mask, active_subpass, rp_handle,
+                            validation_error_map[VALIDATION_ERROR_1b80092c]);
+        }
+        if (0 != buffer_mem_barrier_count) {
+            skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
+                            rp_handle, __LINE__, VALIDATION_ERROR_1b800934, "CORE",
+                            "%s: bufferMemoryBarrierCount is non-zero (%d) for "
+                            "subpass %d of renderPass 0x%" PRIx64 ". %s",
+                            funcName, buffer_mem_barrier_count, active_subpass, rp_handle,
+                            validation_error_map[VALIDATION_ERROR_1b800934]);
+        }
+        const auto &sub_src_access_mask = sub_dep.srcAccessMask;
+        const auto &sub_dst_access_mask = sub_dep.dstAccessMask;
+        for (uint32_t i = 0; i < mem_barrier_count; ++i) {
+            const auto &mb_src_access_mask = mem_barriers[i].srcAccessMask;
+            if (mb_src_access_mask != (sub_src_access_mask & mb_src_access_mask)) {
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE",
+                                "%s: Barrier pMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency "
+                                "srcAccessMask(0x%X) of "
+                                "subpass %d of renderPass 0x%" PRIx64 ". %s",
+                                funcName, i, mb_src_access_mask, sub_src_access_mask, active_subpass, rp_handle,
+                                validation_error_map[VALIDATION_ERROR_1b80092e]);
+            }
+            const auto &mb_dst_access_mask = mem_barriers[i].dstAccessMask;
+            if (mb_dst_access_mask != (sub_dst_access_mask & mb_dst_access_mask)) {
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE",
+                                "%s: Barrier pMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency "
+                                "dstAccessMask(0x%X) of "
+                                "subpass %d of renderPass 0x%" PRIx64 ". %s",
+                                funcName, i, mb_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle,
+                                validation_error_map[VALIDATION_ERROR_1b800930]);
+            }
+        }
+        skip |= ValidateRenderPassImageBarriers(device_data, funcName, cb_state, active_subpass, sub_desc, rp_handle,
+                                                sub_src_access_mask, sub_dst_access_mask, image_mem_barrier_count, image_barriers);
         if (sub_dep.dependencyFlags != dependency_flags) {
             skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
                             rp_handle, __LINE__, VALIDATION_ERROR_1b800932, "CORE",