diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2017-02-01 09:03:06 -0700 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2017-02-02 10:02:21 -0700 |
| commit | 9996425e3cb273d2a05b53a33a5deab9fd83f03f (patch) | |
| tree | f46e934ac71df21c4386046f9d9f0bdb86872788 /layers/core_validation.cpp | |
| parent | 5e6c61ac0c4970434a40caabee2739263355b6e0 (diff) | |
| download | usermoji-9996425e3cb273d2a05b53a33a5deab9fd83f03f.tar.xz | |
layers: Move image validation support to buffer_val
Moved the new CmdClear[Color/DepthStencil]Image support routines
to the buffer_validation module, along with some related helper
functions.
Change-Id: I76a4b545e696bbc770ef0c672d14c92e4a941e49
Diffstat (limited to 'layers/core_validation.cpp')
| -rw-r--r-- | layers/core_validation.cpp | 214 |
1 files changed, 10 insertions, 204 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp index a4cde252..4ab00388 100644 --- a/layers/core_validation.cpp +++ b/layers/core_validation.cpp @@ -418,7 +418,7 @@ static BINDABLE *GetObjectMemBinding(layer_data *my_data, uint64_t handle, VkDeb return nullptr; } // prototype -static GLOBAL_CB_NODE *getCBNode(layer_data const *, const VkCommandBuffer); +GLOBAL_CB_NODE *getCBNode(layer_data const *, const VkCommandBuffer); // Helper function to validate correct usage bits set for buffers or images // Verify that (actual & desired) flags != 0 or, @@ -577,7 +577,7 @@ static void SetMemoryValid(layer_data *dev_data, VkDeviceMemory mem, uint64_t ha // For given image node // If mem is special swapchain key, then set entire image_state to valid param value // Else set the image's bound memory range to valid param value -static void SetImageMemoryValid(layer_data *dev_data, IMAGE_STATE *image_state, bool valid) { +void SetImageMemoryValid(layer_data *dev_data, IMAGE_STATE *image_state, bool valid) { if (image_state->binding.mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { image_state->valid = valid; } else { @@ -3523,29 +3523,6 @@ void SetLayout(GLOBAL_CB_NODE *pCB, ImageSubresourcePair imgpair, const VkImageL } } -template <class OBJECT, class LAYOUT> -void SetLayout(OBJECT *pObject, ImageSubresourcePair imgpair, const LAYOUT &layout, VkImageAspectFlags aspectMask) { - if (imgpair.subresource.aspectMask & aspectMask) { - imgpair.subresource.aspectMask = aspectMask; - SetLayout(pObject, imgpair, layout); - } -} - -template <class OBJECT, class LAYOUT> -void SetLayout(OBJECT *pObject, VkImage image, VkImageSubresource range, const LAYOUT &layout) { - ImageSubresourcePair imgpair = {image, true, range}; - SetLayout(pObject, imgpair, layout, VK_IMAGE_ASPECT_COLOR_BIT); - SetLayout(pObject, imgpair, layout, VK_IMAGE_ASPECT_DEPTH_BIT); - SetLayout(pObject, imgpair, layout, VK_IMAGE_ASPECT_STENCIL_BIT); - SetLayout(pObject, imgpair, layout, VK_IMAGE_ASPECT_METADATA_BIT); -} - -template <class OBJECT, class LAYOUT> -void SetLayout(OBJECT *pObject, VkImage image, const LAYOUT &layout) { - ImageSubresourcePair imgpair = {image, false, VkImageSubresource()}; - SetLayout(pObject, image, imgpair, layout); -} - void SetLayout(const layer_data *dev_data, GLOBAL_CB_NODE *pCB, VkImageView imageView, const VkImageLayout &layout) { auto view_state = getImageViewState(dev_data, imageView); assert(view_state); @@ -3632,7 +3609,7 @@ static void clearDescriptorPool(layer_data *my_data, const VkDevice device, cons } // For given CB object, fetch associated CB Node from map -static GLOBAL_CB_NODE *getCBNode(layer_data const *my_data, const VkCommandBuffer cb) { +GLOBAL_CB_NODE *getCBNode(layer_data const *my_data, const VkCommandBuffer cb) { auto it = my_data->commandBufferMap.find(cb); if (it == my_data->commandBufferMap.end()) { log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, @@ -3701,9 +3678,9 @@ static bool checkGraphicsOrComputeBit(const layer_data *my_data, VkQueueFlags fl return false; } -// Validate the given command being added to the specified cmd buffer, flagging errors if CB is not -// in the recording state or if there's an issue with the Cmd ordering -static bool ValidateCmd(layer_data *my_data, GLOBAL_CB_NODE *pCB, const CMD_TYPE cmd, const char *caller_name) { +// Validate the given command being added to the specified cmd buffer, flagging errors if CB is not in the recording state or if +// there's an issue with the Cmd ordering +bool ValidateCmd(layer_data *my_data, GLOBAL_CB_NODE *pCB, const CMD_TYPE cmd, const char *caller_name) { bool skip_call = false; auto pPool = getCommandPoolNode(my_data, pCB->createInfo.commandPool); if (pPool) { @@ -3774,7 +3751,7 @@ static bool ValidateCmd(layer_data *my_data, GLOBAL_CB_NODE *pCB, const CMD_TYPE return skip_call; } -static void UpdateCmdBufferLastCmd(layer_data *my_data, GLOBAL_CB_NODE *cb_state, const CMD_TYPE cmd) { +void UpdateCmdBufferLastCmd(layer_data *my_data, GLOBAL_CB_NODE *cb_state, const CMD_TYPE cmd) { if (cb_state->state == CB_RECORDING) { cb_state->last_cmd = cmd; } @@ -3970,10 +3947,9 @@ static void set_cb_pso_status(GLOBAL_CB_NODE *pCB, const PIPELINE_STATE *pPipe) } } -// Flags validation error if the associated call is made inside a render pass. The apiName -// routine should ONLY be called outside a render pass. -static bool insideRenderPass(const layer_data *my_data, GLOBAL_CB_NODE *pCB, const char *apiName, - UNIQUE_VALIDATION_ERROR_CODE msgCode) { +// Flags validation error if the associated call is made inside a render pass. The apiName routine should ONLY be called outside a +// render pass. +bool insideRenderPass(const layer_data *my_data, GLOBAL_CB_NODE *pCB, const char *apiName, UNIQUE_VALIDATION_ERROR_CODE msgCode) { bool inside = false; if (pCB->activeRenderPass) { inside = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, @@ -6405,42 +6381,6 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateI return result; } -static void ResolveRemainingLevelsLayers(layer_data *dev_data, VkImageSubresourceRange *range, VkImage image) { - // Expects global_lock to be held by caller - - auto image_state = getImageState(dev_data, image); - if (image_state) { - // If the caller used the special values VK_REMAINING_MIP_LEVELS and VK_REMAINING_ARRAY_LAYERS, resolve them now in our - // internal state to the actual values. - if (range->levelCount == VK_REMAINING_MIP_LEVELS) { - range->levelCount = image_state->createInfo.mipLevels - range->baseMipLevel; - } - - if (range->layerCount == VK_REMAINING_ARRAY_LAYERS) { - range->layerCount = image_state->createInfo.arrayLayers - range->baseArrayLayer; - } - } -} - -// Return the correct layer/level counts if the caller used the special -// values VK_REMAINING_MIP_LEVELS or VK_REMAINING_ARRAY_LAYERS. -static void ResolveRemainingLevelsLayers(layer_data *dev_data, uint32_t *levels, uint32_t *layers, VkImageSubresourceRange range, - VkImage image) { - // Expects global_lock to be held by caller - - *levels = range.levelCount; - *layers = range.layerCount; - auto image_state = getImageState(dev_data, image); - if (image_state) { - if (range.levelCount == VK_REMAINING_MIP_LEVELS) { - *levels = image_state->createInfo.mipLevels - range.baseMipLevel; - } - if (range.layerCount == VK_REMAINING_ARRAY_LAYERS) { - *layers = image_state->createInfo.arrayLayers - range.baseArrayLayer; - } - } -} - // For the given format verify that the aspect masks make sense static bool ValidateImageAspectMask(layer_data *dev_data, VkImage image, VkFormat format, VkImageAspectFlags aspect_mask, const char *func_name) { @@ -8206,83 +8146,6 @@ static bool VerifyDestImageLayout(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, return skip_call; } -static bool VerifyClearImageLayout(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, VkImage image, VkImageSubresourceRange range, - VkImageLayout dest_image_layout, const char *func_name) { - bool skip = false; - - VkImageSubresourceRange resolved_range = range; - ResolveRemainingLevelsLayers(dev_data, &resolved_range, image); - - if (dest_image_layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { - if (dest_image_layout == VK_IMAGE_LAYOUT_GENERAL) { - auto image_state = getImageState(dev_data, image); - if (image_state->createInfo.tiling != VK_IMAGE_TILING_LINEAR) { - // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning. - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0, - 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", - "%s: Layout for cleared image should be TRANSFER_DST_OPTIMAL instead of GENERAL.", func_name); - } - } else { - UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_01086; - if (strcmp(func_name, "vkCmdClearDepthStencilImage()") == 0) { - error_code = VALIDATION_ERROR_01101; - } else { - assert(strcmp(func_name, "vkCmdClearColorImage()") == 0); - } - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__, - error_code, "DS", - "%s: Layout for cleared image is %s but can only be " - "TRANSFER_DST_OPTIMAL or GENERAL. %s", - func_name, string_VkImageLayout(dest_image_layout), validation_error_map[error_code]); - } - } - - for (uint32_t level_index = 0; level_index < resolved_range.levelCount; ++level_index) { - uint32_t level = level_index + resolved_range.baseMipLevel; - for (uint32_t layer_index = 0; layer_index < resolved_range.layerCount; ++layer_index) { - uint32_t layer = layer_index + resolved_range.baseArrayLayer; - VkImageSubresource sub = {resolved_range.aspectMask, level, layer}; - IMAGE_CMD_BUF_LAYOUT_NODE node; - if (FindLayout(cb_node, image, sub, node)) { - if (node.layout != dest_image_layout) { - UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_01085; - if (strcmp(func_name, "vkCmdClearDepthStencilImage()") == 0) { - error_code = VALIDATION_ERROR_01100; - } else { - assert(strcmp(func_name, "vkCmdClearColorImage()") == 0); - } - skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, error_code, "DS", - "%s: Cannot clear an image whose layout is %s and " - "doesn't match the current layout %s. %s", - func_name, string_VkImageLayout(dest_image_layout), string_VkImageLayout(node.layout), - validation_error_map[error_code]); - } - } - } - } - - return skip; -} - -static void RecordClearImageLayout(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, VkImage image, VkImageSubresourceRange range, - VkImageLayout dest_image_layout) { - VkImageSubresourceRange resolved_range = range; - ResolveRemainingLevelsLayers(dev_data, &resolved_range, image); - - for (uint32_t level_index = 0; level_index < resolved_range.levelCount; ++level_index) { - uint32_t level = level_index + resolved_range.baseMipLevel; - for (uint32_t layer_index = 0; layer_index < resolved_range.layerCount; ++layer_index) { - uint32_t layer = layer_index + resolved_range.baseArrayLayer; - VkImageSubresource sub = {resolved_range.aspectMask, level, layer}; - IMAGE_CMD_BUF_LAYOUT_NODE node; - if (!FindLayout(cb_node, image, sub, node)) { - SetLayout(cb_node, image, sub, IMAGE_CMD_BUF_LAYOUT_NODE(dest_image_layout, dest_image_layout)); - } - } - } -} - // Test if two VkExtent3D structs are equivalent static inline bool IsExtentEqual(const VkExtent3D *extent, const VkExtent3D *other_extent) { bool result = true; @@ -8867,45 +8730,6 @@ VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, ui if (!skip) dev_data->dispatch_table.CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects); } -static bool PreCallValidateCmdClearColorImage(layer_data *dev_data, VkCommandBuffer commandBuffer, VkImage image, - VkImageLayout imageLayout, uint32_t rangeCount, - const VkImageSubresourceRange *pRanges) { - bool skip = false; - // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state - auto cb_node = getCBNode(dev_data, commandBuffer); - auto image_state = getImageState(dev_data, image); - if (cb_node && image_state) { - skip |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCmdClearColorImage()", VALIDATION_ERROR_02527); - skip |= ValidateCmd(dev_data, cb_node, CMD_CLEARCOLORIMAGE, "vkCmdClearColorImage()"); - skip |= insideRenderPass(dev_data, cb_node, "vkCmdClearColorImage()", VALIDATION_ERROR_01096); - for (uint32_t i = 0; i < rangeCount; ++i) { - skip |= ValidateImageAttributes(dev_data, image_state, pRanges[i]); - skip |= VerifyClearImageLayout(dev_data, cb_node, image, pRanges[i], imageLayout, "vkCmdClearColorImage()"); - } - } - return skip; -} - -// This state recording routine is shared between ClearColorImage and ClearDepthStencilImage -static void PreCallRecordCmdClearImage(layer_data *dev_data, VkCommandBuffer commandBuffer, VkImage image, - VkImageLayout imageLayout, uint32_t rangeCount, const VkImageSubresourceRange *pRanges, - CMD_TYPE cmd_type) { - auto cb_node = getCBNode(dev_data, commandBuffer); - auto image_state = getImageState(dev_data, image); - if (cb_node && image_state) { - AddCommandBufferBindingImage(dev_data, cb_node, image_state); - std::function<bool()> function = [=]() { - SetImageMemoryValid(dev_data, image_state, true); - return false; - }; - cb_node->validate_functions.push_back(function); - UpdateCmdBufferLastCmd(dev_data, cb_node, cmd_type); - for (uint32_t i = 0; i < rangeCount; ++i) { - RecordClearImageLayout(dev_data, cb_node, image, pRanges[i], imageLayout); - } - } -} - VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue *pColor, uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { @@ -8920,24 +8744,6 @@ VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkI } } -static bool PreCallValidateCmdClearDepthStencilImage(layer_data *dev_data, VkCommandBuffer commandBuffer, VkImage image, - VkImageLayout imageLayout, uint32_t rangeCount, - const VkImageSubresourceRange *pRanges) { - bool skip = false; - // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state - auto cb_node = getCBNode(dev_data, commandBuffer); - auto image_state = getImageState(dev_data, image); - if (cb_node && image_state) { - skip |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_02528); - skip |= ValidateCmd(dev_data, cb_node, CMD_CLEARDEPTHSTENCILIMAGE, "vkCmdClearDepthStencilImage()"); - skip |= insideRenderPass(dev_data, cb_node, "vkCmdClearDepthStencilImage()", VALIDATION_ERROR_01111); - for (uint32_t i = 0; i < rangeCount; ++i) { - skip |= VerifyClearImageLayout(dev_data, cb_node, image, pRanges[i], imageLayout, "vkCmdClearDepthStencilImage()"); - } - } - return skip; -} - VKAPI_ATTR void VKAPI_CALL CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { |
