diff options
| author | Tobin Ehlis <tobine@google.com> | 2017-07-21 14:12:23 -0600 |
|---|---|---|
| committer | Tobin Ehlis <tobine@google.com> | 2017-07-24 15:28:18 -0600 |
| commit | 81d2a7c736eb3102b215c6e00531a8afba581d7d (patch) | |
| tree | 9ea36dba193a62717c71f370d0b72490f237563c /layers/core_validation.cpp | |
| parent | 5b1174d3df2ba6b1450a73495b37a60e15f00b45 (diff) | |
| download | usermoji-81d2a7c736eb3102b215c6e00531a8afba581d7d.tar.xz | |
layers:Refactor image barrier validation
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.
Diffstat (limited to 'layers/core_validation.cpp')
| -rw-r--r-- | layers/core_validation.cpp | 201 |
1 files changed, 108 insertions, 93 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index 6a66a5f4..00e36a8d 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -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", |
