Fix assert for layouts.
authorMichael Lentine <mlentine@google.com>
Fri, 4 Mar 2016 00:30:28 +0000 (18:30 -0600)
committerTobin Ehlis <tobine@google.com>
Mon, 7 Mar 2016 16:22:19 +0000 (09:22 -0700)
Currently we assume that the layout must have been set for a subresource.
While this is true it may be set globally instead of on that specific
subresource directly causing the old assert to throw.

layers/draw_state.cpp

index 5c27d22..7f0b962 100644 (file)
@@ -2525,6 +2525,67 @@ static VkBool32 validateSampler(const layer_data* my_data, const VkSampler* pSam
     return skipCall;
 }
 
+// find layout(s) on the cmd buf level
+bool FindLayout(const GLOBAL_CB_NODE *pCB, VkImage image,
+                VkImageSubresource range, IMAGE_CMD_BUF_NODE &node) {
+    ImageSubresourcePair imgpair = {image, true, range};
+    auto imgsubIt = pCB->imageLayoutMap.find(imgpair);
+    if (imgsubIt == pCB->imageLayoutMap.end()) {
+        imgpair = {image, false, VkImageSubresource()};
+        imgsubIt = pCB->imageLayoutMap.find(imgpair);
+        if (imgsubIt == pCB->imageLayoutMap.end())
+            return false;
+    }
+    node = imgsubIt->second;
+    return true;
+}
+
+// find layout(s) on the global level
+bool FindLayout(const layer_data *my_data, ImageSubresourcePair imgpair,
+                VkImageLayout &layout) {
+    auto imgsubIt = my_data->imageLayoutMap.find(imgpair);
+    if (imgsubIt == my_data->imageLayoutMap.end()) {
+        imgpair = {imgpair.image, false, VkImageSubresource()};
+        imgsubIt = my_data->imageLayoutMap.find(imgpair);
+        if(imgsubIt == my_data->imageLayoutMap.end()) return false;
+    }
+    layout = imgsubIt->second.layout;
+    return true;
+}
+
+bool FindLayout(const layer_data *my_data, VkImage image,
+                VkImageSubresource range, VkImageLayout &layout) {
+    ImageSubresourcePair imgpair = {image, true, range};
+    return FindLayout(my_data, imgpair, layout);
+}
+
+bool FindLayouts(const layer_data *my_data, VkImage image,
+                 std::vector<VkImageLayout> &layouts) {
+    auto sub_data = my_data->imageSubresourceMap.find(image);
+    if (sub_data == my_data->imageSubresourceMap.end())
+        return false;
+    auto imgIt = my_data->imageMap.find(image);
+    if (imgIt == my_data->imageMap.end())
+        return false;
+    bool ignoreGlobal = false;
+    // TODO: Make this robust for >1 aspect mask. Now it will just say ignore
+    // potential errors in this case.
+    if (sub_data->second.size() >=
+        (imgIt->second->arrayLayers * imgIt->second->mipLevels + 1)) {
+        ignoreGlobal = true;
+    }
+    for (auto imgsubpair : sub_data->second) {
+        if (ignoreGlobal && !imgsubpair.hasSubresource)
+            continue;
+        auto img_data = my_data->imageLayoutMap.find(imgsubpair);
+        if (img_data != my_data->imageLayoutMap.end()) {
+            layouts.push_back(img_data->second.layout);
+        }
+    }
+    return true;
+}
+
+
 // Set the layout on the global level
 void SetLayout(layer_data *my_data, ImageSubresourcePair imgpair,
                const VkImageLayout &layout) {
@@ -2567,11 +2628,18 @@ void SetLayout(GLOBAL_CB_NODE *pCB, VkImage image, ImageSubresourcePair imgpair,
 
 void SetLayout(GLOBAL_CB_NODE *pCB, VkImage image, ImageSubresourcePair imgpair,
                const VkImageLayout &layout) {
-    pCB->imageLayoutMap[imgpair].layout = layout;
     // TODO (mlentine): Maybe make vector a set?
-    assert(std::find(pCB->imageSubresourceMap[image].begin(),
-                     pCB->imageSubresourceMap[image].end(),
-                     imgpair) != pCB->imageSubresourceMap[image].end());
+    if(std::find(pCB->imageSubresourceMap[image].begin(),
+                 pCB->imageSubresourceMap[image].end(),
+                 imgpair) != pCB->imageSubresourceMap[image].end()) {
+        pCB->imageLayoutMap[imgpair].layout = layout;
+    } else {
+        // TODO (mlentine): Could be expensive and might need to be removed.
+        assert(imgpair.hasSubresource);
+        IMAGE_CMD_BUF_NODE node;
+        FindLayout(pCB, image, imgpair.subresource, node);
+        SetLayout(pCB, image, imgpair, {node.initialLayout, layout});
+    }
 }
 
 void SetLayout(GLOBAL_CB_NODE *pCB, VkImage image,
@@ -2616,66 +2684,6 @@ void SetLayout(const layer_data *dev_data, GLOBAL_CB_NODE *pCB,
     }
 }
 
-// find layout(s) on the cmd buf level
-bool FindLayout(const GLOBAL_CB_NODE *pCB, VkImage image,
-                VkImageSubresource range, IMAGE_CMD_BUF_NODE &node) {
-    ImageSubresourcePair imgpair = {image, true, range};
-    auto imgsubIt = pCB->imageLayoutMap.find(imgpair);
-    if (imgsubIt == pCB->imageLayoutMap.end()) {
-        imgpair = {image, false, VkImageSubresource()};
-        imgsubIt = pCB->imageLayoutMap.find(imgpair);
-        if (imgsubIt == pCB->imageLayoutMap.end())
-            return false;
-    }
-    node = imgsubIt->second;
-    return true;
-}
-
-// find layout(s) on the global level
-bool FindLayout(const layer_data *my_data, ImageSubresourcePair imgpair,
-                VkImageLayout &layout) {
-    auto imgsubIt = my_data->imageLayoutMap.find(imgpair);
-    if (imgsubIt == my_data->imageLayoutMap.end()) {
-        imgpair = {imgpair.image, false, VkImageSubresource()};
-        imgsubIt = my_data->imageLayoutMap.find(imgpair);
-        if(imgsubIt == my_data->imageLayoutMap.end()) return false;
-    }
-    layout = imgsubIt->second.layout;
-    return true;
-}
-
-bool FindLayout(const layer_data *my_data, VkImage image,
-                VkImageSubresource range, VkImageLayout &layout) {
-    ImageSubresourcePair imgpair = {image, true, range};
-    return FindLayout(my_data, imgpair, layout);
-}
-
-bool FindLayouts(const layer_data *my_data, VkImage image,
-                 std::vector<VkImageLayout> &layouts) {
-    auto sub_data = my_data->imageSubresourceMap.find(image);
-    if (sub_data == my_data->imageSubresourceMap.end())
-        return false;
-    auto imgIt = my_data->imageMap.find(image);
-    if (imgIt == my_data->imageMap.end())
-        return false;
-    bool ignoreGlobal = false;
-    // TODO: Make this robust for >1 aspect mask. Now it will just say ignore
-    // potential errors in this case.
-    if (sub_data->second.size() >=
-        (imgIt->second->arrayLayers * imgIt->second->mipLevels + 1)) {
-        ignoreGlobal = true;
-    }
-    for (auto imgsubpair : sub_data->second) {
-        if (ignoreGlobal && !imgsubpair.hasSubresource)
-            continue;
-        auto img_data = my_data->imageLayoutMap.find(imgsubpair);
-        if (img_data != my_data->imageLayoutMap.end()) {
-            layouts.push_back(img_data->second.layout);
-        }
-    }
-    return true;
-}
-
 // Verify that given imageView is valid
 static VkBool32 validateImageView(const layer_data* my_data, const VkImageView* pImageView, const VkImageLayout imageLayout)
 {