intel: fix copying of create info
For XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO, we need to do a deep copy. To
achieve, we need to derive the type of the create info from within
intel_base_dbg_create().
As usual, this is untested.
diff --git a/icd/intel/obj.c b/icd/intel/obj.c
index 2ea35f4..f6b6e15 100644
--- a/icd/intel/obj.c
+++ b/icd/intel/obj.c
@@ -61,13 +61,103 @@
return ret;
}
+static bool base_dbg_copy_create_info(struct intel_base_dbg *dbg,
+ const void *create_info)
+{
+ const union {
+ const void *ptr;
+ const struct {
+ XGL_STRUCTURE_TYPE struct_type;
+ XGL_VOID *next;
+ } *header;
+ } info = { .ptr = create_info };
+ XGL_SIZE shallow_copy = 0;
+
+ if (!create_info)
+ return true;
+
+ switch (info.header->struct_type) {
+ case XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO:
+ assert(dbg->type == XGL_DBG_OBJECT_DEVICE);
+ break;
+ case XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO:
+ assert(dbg->type == XGL_DBG_OBJECT_GPU_MEMORY);
+ shallow_copy = sizeof(XGL_MEMORY_ALLOC_INFO);
+ break;
+ case XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO:
+ assert(dbg->type == XGL_DBG_OBJECT_EVENT);
+ shallow_copy = sizeof(XGL_EVENT_CREATE_INFO);
+ break;
+ case XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO:
+ assert(dbg->type == XGL_DBG_OBJECT_FENCE);
+ shallow_copy = sizeof(XGL_FENCE_CREATE_INFO);
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ if (shallow_copy) {
+ assert(!info.header->next);
+
+ dbg->create_info = icd_alloc(shallow_copy, 0, XGL_SYSTEM_ALLOC_DEBUG);
+ if (!dbg->create_info)
+ return false;
+
+ memcpy(dbg->create_info, create_info, shallow_copy);
+ } else if (info.header->struct_type ==
+ XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO) {
+ const XGL_DEVICE_CREATE_INFO *src = info.ptr;
+ XGL_DEVICE_CREATE_INFO *dst;
+ uint8_t *d;
+ XGL_SIZE size;
+ XGL_UINT i;
+
+ size = sizeof(*src);
+ size += sizeof(src->pRequestedQueues[0]) * src->queueRecordCount;
+ size += sizeof(src->ppEnabledExtensionNames[0]) * src->extensionCount;
+ for (i = 0; i < src->extensionCount; i++) {
+ size += 1 +
+ strlen((const char *) src->ppEnabledExtensionNames[i]);
+ }
+
+ dst = icd_alloc(sizeof(size), 0, XGL_SYSTEM_ALLOC_DEBUG);
+ if (!dst)
+ return false;
+
+ memcpy(dst, src, sizeof(*src));
+
+ d = (uint8_t *) dst;
+ d += sizeof(*src);
+
+ size = sizeof(src->pRequestedQueues[0]) * src->queueRecordCount;
+ memcpy(d, src->pRequestedQueues, size);
+ dst->pRequestedQueues = (const XGL_DEVICE_QUEUE_CREATE_INFO *) d;
+ d += size;
+
+ size = sizeof(src->ppEnabledExtensionNames[0]) * src->extensionCount;
+ dst->ppEnabledExtensionNames = (const XGL_CHAR * const *) d;
+
+ for (i = 0; i < src->extensionCount; i++) {
+ const XGL_SIZE len =
+ strlen((const char *) src->ppEnabledExtensionNames[i]);
+
+ memcpy(d + size, src->ppEnabledExtensionNames[i], len + 1);
+ ((const XGL_CHAR **) d)[i] = (const XGL_CHAR *) (d + size);
+
+ size += len + 1;
+ }
+ }
+
+ return true;
+}
+
/**
* Create an intel_base_dbg. When alloc_size is non-zero, a buffer of that
* size is allocated and zeroed.
*/
struct intel_base_dbg *intel_base_dbg_create(XGL_DBG_OBJECT_TYPE type,
const void *create_info,
- XGL_SIZE create_info_size,
XGL_SIZE alloc_size)
{
struct intel_base_dbg *dbg;
@@ -86,15 +176,9 @@
dbg->alloc_id = icd_get_allocator_id();
dbg->type = type;
- if (create_info_size) {
- dbg->create_info =
- icd_alloc(create_info_size, 0, XGL_SYSTEM_ALLOC_DEBUG);
- if (!dbg->create_info) {
- icd_free(dbg);
- return NULL;
- }
-
- memcpy(dbg->create_info, create_info, create_info_size);
+ if (!base_dbg_copy_create_info(dbg, create_info)) {
+ icd_free(dbg);
+ return NULL;
}
return dbg;