aboutsummaryrefslogtreecommitdiff
path: root/loader/debug_report.c
diff options
context:
space:
mode:
authorIan Elliott <ianelliott@google.com>2016-03-31 10:48:19 -0600
committerJon Ashburn <jon@lunarg.com>2016-04-01 12:14:32 -0600
commite6ae483aedfb9f0e64697d4df0ff53519dd19957 (patch)
treeb8f585761772875b90f86fc5822a5becf51c9c36 /loader/debug_report.c
parent7c50ad62d53a2271ee638a68dd20fc7c00501c6c (diff)
downloadusermoji-e6ae483aedfb9f0e64697d4df0ff53519dd19957.tar.xz
loader: vk{Create|Destroy}Instance can have multiple tmp callbacks
During code review of the Android version of the temporary debug_report callbacks code, it was decided to allow an array of VkDebugReportCallbackCreateInfoEXT structs to be passed to vkCreateInstance(). This code implements that, using some new utility functions in order to help keep the code clean.
Diffstat (limited to 'loader/debug_report.c')
-rw-r--r--loader/debug_report.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/loader/debug_report.c b/loader/debug_report.c
index 7da370ce..3f49aa8c 100644
--- a/loader/debug_report.c
+++ b/loader/debug_report.c
@@ -156,6 +156,114 @@ void util_DestroyDebugReportCallback(struct loader_instance *inst,
}
}
+// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
+// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It
+// then allocates array that can hold that many structs, as well as that many
+// VkDebugReportCallbackEXT handles. It then copies each
+// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
+VkResult
+util_CopyDebugReportCreateInfos(const void *pChain,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t *num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT **infos,
+ VkDebugReportCallbackEXT **callbacks)
+{
+ uint32_t n = *num_callbacks = 0;
+
+ // NOTE: The loader is not using pAllocator, and so this function doesn't
+ // either.
+
+ const void *pNext = pChain;
+ while (pNext) {
+ // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
+ if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType ==
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
+ n++;
+ }
+ pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
+ }
+ if (n == 0) {
+ return VK_SUCCESS;
+ }
+
+ // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
+ VkDebugReportCallbackCreateInfoEXT *pInfos =
+ *infos = ((VkDebugReportCallbackCreateInfoEXT *)
+ malloc(n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
+ if (!pInfos) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ // 3rd, allocate memory for a unique handle for each callback:
+ VkDebugReportCallbackEXT *pCallbacks =
+ *callbacks = ((VkDebugReportCallbackEXT *)
+ malloc(n * sizeof(VkDebugReportCallbackEXT)));
+ if (!pCallbacks) {
+ free(pInfos);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
+ // vkDestroyInstance, and assign a unique handle to each callback (just
+ // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
+ pNext = pChain;
+ while (pNext) {
+ if (((VkInstanceCreateInfo *)pNext)->sType ==
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
+ memcpy(pInfos, pNext,
+ sizeof(VkDebugReportCallbackCreateInfoEXT));
+ *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++;
+ }
+ pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
+ }
+
+ *num_callbacks = n;
+ return VK_SUCCESS;
+}
+
+void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator,
+ VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks)
+{
+ free(infos);
+ free(callbacks);
+}
+
+VkResult
+util_CreateDebugReportCallbacks(struct loader_instance *inst,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks)
+{
+ VkResult rtn;
+ for (uint32_t i = 0 ; i < num_callbacks ; i++) {
+ rtn = util_CreateDebugReportCallback(inst,
+ &infos[i],
+ pAllocator,
+ callbacks[i]);
+ if (rtn != VK_SUCCESS) {
+ for (uint32_t j = 0 ; j < i ; j++) {
+ util_DestroyDebugReportCallback(inst,
+ callbacks[j],
+ pAllocator);
+ }
+ return rtn;
+ }
+ }
+ return rtn;
+}
+
+void util_DestroyDebugReportCallbacks(struct loader_instance *inst,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks,
+ VkDebugReportCallbackEXT *callbacks)
+{
+ for (uint32_t i = 0 ; i < num_callbacks ; i++) {
+ util_DestroyDebugReportCallback(inst,
+ callbacks[i],
+ pAllocator);
+ }
+}
+
static VKAPI_ATTR void VKAPI_CALL
debug_report_DestroyDebugReportCallback(VkInstance instance,
VkDebugReportCallbackEXT callback,