// Now update CBInfo's Mem reference list
cb_node->memObjs.insert(img_node->mem);
}
+ cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(img_node->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT});
}
// Now update cb binding for image
img_node->cb_bindings.insert(cb_node);
pMemInfo->commandBufferBindings.insert(cb_node->commandBuffer);
// Now update CBInfo's Mem reference list
cb_node->memObjs.insert(buff_node->mem);
+ cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(buff_node->buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT});
}
// Now update cb binding for buffer
buff_node->cb_bindings.insert(cb_node);
}
return skip_call;
}
+// For a given object, if cb_node is in that objects cb_bindings, remove cb_node
+static void removeCommandBufferBinding(layer_data *dev_data, VK_OBJECT const *object, GLOBAL_CB_NODE *cb_node) {
+ switch (object->type) {
+ case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
+ auto img_node = getImageNode(dev_data, reinterpret_cast<VkImage>(object->handle));
+ if (img_node)
+ img_node->cb_bindings.erase(cb_node);
+ break;
+ }
+ case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
+ auto buf_node = getBufferNode(dev_data, reinterpret_cast<VkBuffer>(object->handle));
+ if (buf_node)
+ buf_node->cb_bindings.erase(cb_node);
+ break;
+ }
+ default:
+ assert(0); // unhandled object type
+ }
+}
// Reset the command buffer state
// Maintain the createInfo and set state to CB_NEW, but clear all other state
static void resetCB(layer_data *dev_data, const VkCommandBuffer cb) {
pCB->eventUpdates.clear();
pCB->queryUpdates.clear();
+ // Remove object bindings
+ for (auto obj : pCB->object_bindings) {
+ removeCommandBufferBinding(dev_data, &obj, pCB);
+ }
// Remove this cmdBuffer's reference from each FrameBuffer's CB ref list
for (auto framebuffer : pCB->framebuffers) {
auto fb_node = getFramebuffer(dev_data, framebuffer);
VkDebugReportObjectTypeEXT type;
};
+inline bool operator==(VK_OBJECT a, VK_OBJECT b) NOEXCEPT { return a.handle == b.handle && a.type == b.type; }
+
+namespace std {
+template <> struct hash<VK_OBJECT> {
+ size_t operator()(VK_OBJECT obj) const NOEXCEPT { return hash<uint64_t>()(obj.handle) ^ hash<uint32_t>()(obj.type); }
+};
+}
+
struct DESCRIPTOR_POOL_NODE {
VkDescriptorPool pool;
uint32_t maxSets; // Max descriptor sets allowed in this pool
};
// Simple struct to hold handle and type of object so they can be uniquely identified and looked up in appropriate map
+// TODO : Unify this with VK_OBJECT above
struct MT_OBJ_HANDLE_TYPE {
uint64_t handle;
VkDebugReportObjectTypeEXT type;
uint32_t activeSubpass;
VkFramebuffer activeFramebuffer;
std::unordered_set<VkFramebuffer> framebuffers;
- // Unified data struct to track dependencies that have been broken
- // These are either destroyed objects, or updated descriptor sets
+ // Unified data structs to track objects bound to this command buffer as well as object
+ // dependencies that have been broken : either destroyed objects, or updated descriptor sets
+ std::unordered_set<VK_OBJECT> object_bindings;
std::vector<VK_OBJECT> broken_bindings;
+
std::unordered_set<VkEvent> waitedEvents;
std::vector<VkEvent> writeEventsBeforeWait;
std::vector<VkEvent> events;