[PATCH 2/9] winevulkan: Generate conversion function for VkDeviceCreateInfo structure extensions.

Józef Kucia jkucia at codeweavers.com
Wed Apr 10 04:59:50 CDT 2019


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/winevulkan/make_vulkan     |   1 +
 dlls/winevulkan/vulkan.c        | 168 +++------
 dlls/winevulkan/vulkan_thunks.c | 579 ++++++++++++++++++++++++++++++++
 dlls/winevulkan/vulkan_thunks.h |   2 +
 4 files changed, 622 insertions(+), 128 deletions(-)

diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index eb68a7be598f..af3765762680 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -221,6 +221,7 @@ FUNCTION_OVERRIDES = {
 }
 
 STRUCT_CHAIN_CONVERSIONS = [
+    "VkDeviceCreateInfo",
     "VkInstanceCreateInfo",
 ]
 
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 259d7d18e7c1..725bdf019e2c 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -207,128 +207,48 @@ static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
     return queues;
 }
 
-static void *convert_VkPhysicalDeviceFeatures2(const void *src)
-{
-    const VkPhysicalDeviceFeatures2 *in = src;
-    VkPhysicalDeviceFeatures2 *out;
-
-    if (!(out = heap_alloc(sizeof(*out))))
-        return NULL;
-
-    *out = *in;
-    out->pNext = NULL;
-
-    return out;
-}
-
-static void *convert_VkDeviceGroupDeviceCreateInfo(const void *src)
-{
-    const VkDeviceGroupDeviceCreateInfo *in = src;
-    VkDeviceGroupDeviceCreateInfo *out;
-    VkPhysicalDevice *physical_devices;
-    unsigned int i;
-
-    if (!(out = heap_alloc(sizeof(*out))))
-        return NULL;
-
-    *out = *in;
-    out->pNext = NULL;
-    if (!(physical_devices = heap_calloc(in->physicalDeviceCount, sizeof(*physical_devices))))
-    {
-        heap_free(out);
-        return NULL;
-    }
-    for (i = 0; i < in->physicalDeviceCount; ++i)
-        physical_devices[i] = in->pPhysicalDevices[i]->phys_dev;
-    out->pPhysicalDevices = physical_devices;
-
-    return out;
-}
-
-static void *convert_VkPhysicalDeviceHostQueryResetFeaturesEXT(const void *src)
-{
-    const VkPhysicalDeviceHostQueryResetFeaturesEXT *in = src;
-    VkPhysicalDeviceHostQueryResetFeaturesEXT *out;
-
-    if (!(out = heap_alloc(sizeof(*out))))
-        return NULL;
-
-    *out = *in;
-    out->pNext = NULL;
-
-    return out;
-}
-
 static void wine_vk_device_free_create_info(VkDeviceCreateInfo *create_info)
 {
-    VkPhysicalDeviceHostQueryResetFeaturesEXT *host_query_reset_features;
-    VkPhysicalDeviceFeatures2 *device_features;
     VkDeviceGroupDeviceCreateInfo *group_info;
 
-    device_features = wine_vk_find_struct(create_info, PHYSICAL_DEVICE_FEATURES_2);
-    group_info = wine_vk_find_struct(create_info, DEVICE_GROUP_DEVICE_CREATE_INFO);
-    host_query_reset_features = wine_vk_find_struct(create_info, PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT);
-    create_info->pNext = NULL;
-
-    heap_free(device_features);
-    if (group_info)
+    if ((group_info = wine_vk_find_struct(create_info, DEVICE_GROUP_DEVICE_CREATE_INFO)))
     {
         heap_free((void *)group_info->pPhysicalDevices);
-        heap_free(group_info);
     }
-    heap_free(host_query_reset_features);
+
+    free_VkDeviceCreateInfo_struct_chain(create_info);
 }
 
 static VkResult wine_vk_device_convert_create_info(const VkDeviceCreateInfo *src,
         VkDeviceCreateInfo *dst)
 {
+    VkDeviceGroupDeviceCreateInfo *group_info;
     unsigned int i;
+    VkResult res;
 
     *dst = *src;
 
-    /* Application and loader can pass in a chain of extensions through pNext.
-     * We can't blindly pass these through as often these contain callbacks or
-     * they can even be pass structures for loader / ICD internal use.
-     */
-    if (src->pNext)
+    if ((res = convert_VkDeviceCreateInfo_struct_chain(src->pNext, dst)) < 0)
     {
-        const VkBaseInStructure *header;
-        VkBaseOutStructure *dst_header;
+        WARN("Failed to convert VkDeviceCreateInfo pNext chain, res=%d.\n", res);
+        return res;
+    }
+
+    /* FIXME: convert_VkDeviceCreateInfo_struct_chain() should unwrap handles for us. */
+    if ((group_info = wine_vk_find_struct(dst, DEVICE_GROUP_DEVICE_CREATE_INFO)))
+    {
+        VkPhysicalDevice *physical_devices;
 
-        dst->pNext = NULL;
-        dst_header = (VkBaseOutStructure *)dst;
-        for (header = src->pNext; header; header = header->pNext)
+        if (!(physical_devices = heap_calloc(group_info->physicalDeviceCount, sizeof(*physical_devices))))
+        {
+            free_VkDeviceCreateInfo_struct_chain(dst);
+            return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
+        for (i = 0; i < group_info->physicalDeviceCount; ++i)
         {
-            switch (header->sType)
-            {
-                case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO:
-                    /* Used for loader to ICD communication. Ignore to not confuse
-                     * host loader.
-                     */
-                    break;
-
-                case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO:
-                    if (!(dst_header->pNext = convert_VkDeviceGroupDeviceCreateInfo(header)))
-                        goto err;
-                    dst_header = dst_header->pNext;
-                    break;
-
-                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
-                    if (!(dst_header->pNext = convert_VkPhysicalDeviceFeatures2(header)))
-                        goto err;
-                    dst_header = dst_header->pNext;
-                    break;
-
-                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT:
-                    if (!(dst_header->pNext = convert_VkPhysicalDeviceHostQueryResetFeaturesEXT(header)))
-                        goto err;
-                    dst_header = dst_header->pNext;
-                    break;
-
-                default:
-                    FIXME("Application requested a linked structure of type %u.\n", header->sType);
-            }
+            physical_devices[i] = group_info->pPhysicalDevices[i]->phys_dev;
         }
+        group_info->pPhysicalDevices = physical_devices;
     }
 
     /* Should be filtered out by loader as ICDs don't support layers. */
@@ -343,15 +263,12 @@ static VkResult wine_vk_device_convert_create_info(const VkDeviceCreateInfo *src
         if (!wine_vk_device_extension_supported(extension_name))
         {
             WARN("Extension %s is not supported.\n", debugstr_a(extension_name));
+            wine_vk_device_free_create_info(dst);
             return VK_ERROR_EXTENSION_NOT_PRESENT;
         }
     }
 
     return VK_SUCCESS;
-
-err:
-    wine_vk_device_free_create_info(dst);
-    return VK_ERROR_OUT_OF_HOST_MEMORY;
 }
 
 /* Helper function used for freeing a device structure. This function supports full
@@ -655,21 +572,15 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
 
     res = wine_vk_device_convert_create_info(create_info, &create_info_host);
     if (res != VK_SUCCESS)
-    {
-        if (res != VK_ERROR_EXTENSION_NOT_PRESENT)
-            ERR("Failed to convert VkDeviceCreateInfo, res=%d.\n", res);
-        wine_vk_device_free(object);
-        return res;
-    }
+        goto fail;
 
     res = phys_dev->instance->funcs.p_vkCreateDevice(phys_dev->phys_dev,
             &create_info_host, NULL /* allocator */, &object->device);
     wine_vk_device_free_create_info(&create_info_host);
     if (res != VK_SUCCESS)
     {
-        ERR("Failed to create device.\n");
-        wine_vk_device_free(object);
-        return res;
+        WARN("Failed to create device, res=%d.\n", res);
+        goto fail;
     }
 
     /* Just load all function pointers we are aware off. The loader takes care of filtering.
@@ -679,7 +590,7 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
 #define USE_VK_FUNC(name) \
     object->funcs.p_##name = (void *)vk_funcs->p_vkGetDeviceProcAddr(object->device, #name); \
     if (object->funcs.p_##name == NULL) \
-        TRACE("Not found %s\n", #name);
+        TRACE("Not found '%s'.\n", #name);
     ALL_VK_DEVICE_FUNCS()
 #undef USE_VK_FUNC
 
@@ -689,13 +600,12 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
     phys_dev->instance->funcs.p_vkGetPhysicalDeviceQueueFamilyProperties(phys_dev->phys_dev,
             &max_queue_families, NULL);
     object->max_queue_families = max_queue_families;
-    TRACE("Max queue families: %u\n", object->max_queue_families);
+    TRACE("Max queue families: %u.\n", object->max_queue_families);
 
-    object->queues = heap_calloc(max_queue_families, sizeof(*object->queues));
-    if (!object->queues)
+    if (!(object->queues = heap_calloc(max_queue_families, sizeof(*object->queues))))
     {
-        wine_vk_device_free(object);
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto fail;
     }
 
     for (i = 0; i < create_info_host.queueCreateInfoCount; i++)
@@ -704,15 +614,13 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
         uint32_t family_index = create_info_host.pQueueCreateInfos[i].queueFamilyIndex;
         uint32_t queue_count = create_info_host.pQueueCreateInfos[i].queueCount;
 
-        TRACE("queueFamilyIndex %u, queueCount %u\n", family_index, queue_count);
+        TRACE("Queue family index %u, queue count %u.\n", family_index, queue_count);
 
-        object->queues[family_index] = wine_vk_device_alloc_queues(object, family_index,
-                queue_count, flags);
-        if (!object->queues[family_index])
+        if (!(object->queues[family_index] = wine_vk_device_alloc_queues(object, family_index, queue_count, flags)))
         {
-            ERR("Failed to allocate memory for queues\n");
-            wine_vk_device_free(object);
-            return VK_ERROR_OUT_OF_HOST_MEMORY;
+            ERR("Failed to allocate memory for queues.\n");
+            res = VK_ERROR_OUT_OF_HOST_MEMORY;
+            goto fail;
         }
     }
 
@@ -721,6 +629,10 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
     *device = object;
     TRACE("Created device %p (native device %p).\n", object, object->device);
     return VK_SUCCESS;
+
+fail:
+    wine_vk_device_free(object);
+    return res;
 }
 
 VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_info,
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index 2f0cc6218e22..fc41fb00e330 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -1343,6 +1343,585 @@ static inline void free_VkCopyDescriptorSet_array(VkCopyDescriptorSet_host *in,
 
 #endif /* USE_STRUCT_CONVERSION */
 
+VkResult convert_VkDeviceCreateInfo_struct_chain(const void *pNext, VkDeviceCreateInfo *out_struct)
+{
+    VkBaseOutStructure *out_header = (VkBaseOutStructure *)out_struct;
+    const VkBaseInStructure *in_header;
+
+    out_header->pNext = NULL;
+
+    for (in_header = pNext; in_header; in_header = in_header->pNext)
+    {
+        switch (in_header->sType)
+        {
+        case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO:
+        case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO:
+            break;
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
+        {
+            const VkPhysicalDeviceFeatures2 *in = (const VkPhysicalDeviceFeatures2 *)in_header;
+            VkPhysicalDeviceFeatures2 *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->features = in->features;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES:
+        {
+            const VkPhysicalDeviceVariablePointerFeatures *in = (const VkPhysicalDeviceVariablePointerFeatures *)in_header;
+            VkPhysicalDeviceVariablePointerFeatures *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->variablePointersStorageBuffer = in->variablePointersStorageBuffer;
+            out->variablePointers = in->variablePointers;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES:
+        {
+            const VkPhysicalDeviceMultiviewFeatures *in = (const VkPhysicalDeviceMultiviewFeatures *)in_header;
+            VkPhysicalDeviceMultiviewFeatures *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->multiview = in->multiview;
+            out->multiviewGeometryShader = in->multiviewGeometryShader;
+            out->multiviewTessellationShader = in->multiviewTessellationShader;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO:
+        {
+            const VkDeviceGroupDeviceCreateInfo *in = (const VkDeviceGroupDeviceCreateInfo *)in_header;
+            VkDeviceGroupDeviceCreateInfo *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->physicalDeviceCount = in->physicalDeviceCount;
+            out->pPhysicalDevices = in->pPhysicalDevices;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES:
+        {
+            const VkPhysicalDevice16BitStorageFeatures *in = (const VkPhysicalDevice16BitStorageFeatures *)in_header;
+            VkPhysicalDevice16BitStorageFeatures *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->storageBuffer16BitAccess = in->storageBuffer16BitAccess;
+            out->uniformAndStorageBuffer16BitAccess = in->uniformAndStorageBuffer16BitAccess;
+            out->storagePushConstant16 = in->storagePushConstant16;
+            out->storageInputOutput16 = in->storageInputOutput16;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES:
+        {
+            const VkPhysicalDeviceSamplerYcbcrConversionFeatures *in = (const VkPhysicalDeviceSamplerYcbcrConversionFeatures *)in_header;
+            VkPhysicalDeviceSamplerYcbcrConversionFeatures *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->samplerYcbcrConversion = in->samplerYcbcrConversion;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES:
+        {
+            const VkPhysicalDeviceProtectedMemoryFeatures *in = (const VkPhysicalDeviceProtectedMemoryFeatures *)in_header;
+            VkPhysicalDeviceProtectedMemoryFeatures *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->protectedMemory = in->protectedMemory;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *in = (const VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *)in_header;
+            VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->advancedBlendCoherentOperations = in->advancedBlendCoherentOperations;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceInlineUniformBlockFeaturesEXT *in = (const VkPhysicalDeviceInlineUniformBlockFeaturesEXT *)in_header;
+            VkPhysicalDeviceInlineUniformBlockFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->inlineUniformBlock = in->inlineUniformBlock;
+            out->descriptorBindingInlineUniformBlockUpdateAfterBind = in->descriptorBindingInlineUniformBlockUpdateAfterBind;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES:
+        {
+            const VkPhysicalDeviceShaderDrawParameterFeatures *in = (const VkPhysicalDeviceShaderDrawParameterFeatures *)in_header;
+            VkPhysicalDeviceShaderDrawParameterFeatures *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->shaderDrawParameters = in->shaderDrawParameters;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceHostQueryResetFeaturesEXT *in = (const VkPhysicalDeviceHostQueryResetFeaturesEXT *)in_header;
+            VkPhysicalDeviceHostQueryResetFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->hostQueryReset = in->hostQueryReset;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceDescriptorIndexingFeaturesEXT *in = (const VkPhysicalDeviceDescriptorIndexingFeaturesEXT *)in_header;
+            VkPhysicalDeviceDescriptorIndexingFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->shaderInputAttachmentArrayDynamicIndexing = in->shaderInputAttachmentArrayDynamicIndexing;
+            out->shaderUniformTexelBufferArrayDynamicIndexing = in->shaderUniformTexelBufferArrayDynamicIndexing;
+            out->shaderStorageTexelBufferArrayDynamicIndexing = in->shaderStorageTexelBufferArrayDynamicIndexing;
+            out->shaderUniformBufferArrayNonUniformIndexing = in->shaderUniformBufferArrayNonUniformIndexing;
+            out->shaderSampledImageArrayNonUniformIndexing = in->shaderSampledImageArrayNonUniformIndexing;
+            out->shaderStorageBufferArrayNonUniformIndexing = in->shaderStorageBufferArrayNonUniformIndexing;
+            out->shaderStorageImageArrayNonUniformIndexing = in->shaderStorageImageArrayNonUniformIndexing;
+            out->shaderInputAttachmentArrayNonUniformIndexing = in->shaderInputAttachmentArrayNonUniformIndexing;
+            out->shaderUniformTexelBufferArrayNonUniformIndexing = in->shaderUniformTexelBufferArrayNonUniformIndexing;
+            out->shaderStorageTexelBufferArrayNonUniformIndexing = in->shaderStorageTexelBufferArrayNonUniformIndexing;
+            out->descriptorBindingUniformBufferUpdateAfterBind = in->descriptorBindingUniformBufferUpdateAfterBind;
+            out->descriptorBindingSampledImageUpdateAfterBind = in->descriptorBindingSampledImageUpdateAfterBind;
+            out->descriptorBindingStorageImageUpdateAfterBind = in->descriptorBindingStorageImageUpdateAfterBind;
+            out->descriptorBindingStorageBufferUpdateAfterBind = in->descriptorBindingStorageBufferUpdateAfterBind;
+            out->descriptorBindingUniformTexelBufferUpdateAfterBind = in->descriptorBindingUniformTexelBufferUpdateAfterBind;
+            out->descriptorBindingStorageTexelBufferUpdateAfterBind = in->descriptorBindingStorageTexelBufferUpdateAfterBind;
+            out->descriptorBindingUpdateUnusedWhilePending = in->descriptorBindingUpdateUnusedWhilePending;
+            out->descriptorBindingPartiallyBound = in->descriptorBindingPartiallyBound;
+            out->descriptorBindingVariableDescriptorCount = in->descriptorBindingVariableDescriptorCount;
+            out->runtimeDescriptorArray = in->runtimeDescriptorArray;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR:
+        {
+            const VkPhysicalDevice8BitStorageFeaturesKHR *in = (const VkPhysicalDevice8BitStorageFeaturesKHR *)in_header;
+            VkPhysicalDevice8BitStorageFeaturesKHR *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->storageBuffer8BitAccess = in->storageBuffer8BitAccess;
+            out->uniformAndStorageBuffer8BitAccess = in->uniformAndStorageBuffer8BitAccess;
+            out->storagePushConstant8 = in->storagePushConstant8;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceConditionalRenderingFeaturesEXT *in = (const VkPhysicalDeviceConditionalRenderingFeaturesEXT *)in_header;
+            VkPhysicalDeviceConditionalRenderingFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->conditionalRendering = in->conditionalRendering;
+            out->inheritedConditionalRendering = in->inheritedConditionalRendering;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR:
+        {
+            const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *in = (const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *)in_header;
+            VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->vulkanMemoryModel = in->vulkanMemoryModel;
+            out->vulkanMemoryModelDeviceScope = in->vulkanMemoryModelDeviceScope;
+            out->vulkanMemoryModelAvailabilityVisibilityChains = in->vulkanMemoryModelAvailabilityVisibilityChains;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR:
+        {
+            const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *in = (const VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *)in_header;
+            VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->shaderBufferInt64Atomics = in->shaderBufferInt64Atomics;
+            out->shaderSharedInt64Atomics = in->shaderSharedInt64Atomics;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *in = (const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)in_header;
+            VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->vertexAttributeInstanceRateDivisor = in->vertexAttributeInstanceRateDivisor;
+            out->vertexAttributeInstanceRateZeroDivisor = in->vertexAttributeInstanceRateZeroDivisor;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceASTCDecodeFeaturesEXT *in = (const VkPhysicalDeviceASTCDecodeFeaturesEXT *)in_header;
+            VkPhysicalDeviceASTCDecodeFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->decodeModeSharedExponent = in->decodeModeSharedExponent;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceTransformFeedbackFeaturesEXT *in = (const VkPhysicalDeviceTransformFeedbackFeaturesEXT *)in_header;
+            VkPhysicalDeviceTransformFeedbackFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->transformFeedback = in->transformFeedback;
+            out->geometryStreams = in->geometryStreams;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV:
+        {
+            const VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV *in = (const VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV *)in_header;
+            VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->representativeFragmentTest = in->representativeFragmentTest;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV:
+        {
+            const VkPhysicalDeviceExclusiveScissorFeaturesNV *in = (const VkPhysicalDeviceExclusiveScissorFeaturesNV *)in_header;
+            VkPhysicalDeviceExclusiveScissorFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->exclusiveScissor = in->exclusiveScissor;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV:
+        {
+            const VkPhysicalDeviceCornerSampledImageFeaturesNV *in = (const VkPhysicalDeviceCornerSampledImageFeaturesNV *)in_header;
+            VkPhysicalDeviceCornerSampledImageFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->cornerSampledImage = in->cornerSampledImage;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV:
+        {
+            const VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *in = (const VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *)in_header;
+            VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->computeDerivativeGroupQuads = in->computeDerivativeGroupQuads;
+            out->computeDerivativeGroupLinear = in->computeDerivativeGroupLinear;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV:
+        {
+            const VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV *in = (const VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV *)in_header;
+            VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->fragmentShaderBarycentric = in->fragmentShaderBarycentric;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV:
+        {
+            const VkPhysicalDeviceShaderImageFootprintFeaturesNV *in = (const VkPhysicalDeviceShaderImageFootprintFeaturesNV *)in_header;
+            VkPhysicalDeviceShaderImageFootprintFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->imageFootprint = in->imageFootprint;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV:
+        {
+            const VkPhysicalDeviceShadingRateImageFeaturesNV *in = (const VkPhysicalDeviceShadingRateImageFeaturesNV *)in_header;
+            VkPhysicalDeviceShadingRateImageFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->shadingRateImage = in->shadingRateImage;
+            out->shadingRateCoarseSampleOrder = in->shadingRateCoarseSampleOrder;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV:
+        {
+            const VkPhysicalDeviceMeshShaderFeaturesNV *in = (const VkPhysicalDeviceMeshShaderFeaturesNV *)in_header;
+            VkPhysicalDeviceMeshShaderFeaturesNV *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->taskShader = in->taskShader;
+            out->meshShader = in->meshShader;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceFragmentDensityMapFeaturesEXT *in = (const VkPhysicalDeviceFragmentDensityMapFeaturesEXT *)in_header;
+            VkPhysicalDeviceFragmentDensityMapFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->fragmentDensityMap = in->fragmentDensityMap;
+            out->fragmentDensityMapDynamic = in->fragmentDensityMapDynamic;
+            out->fragmentDensityMapNonSubsampledImages = in->fragmentDensityMapNonSubsampledImages;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *in = (const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)in_header;
+            VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->scalarBlockLayout = in->scalarBlockLayout;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceDepthClipEnableFeaturesEXT *in = (const VkPhysicalDeviceDepthClipEnableFeaturesEXT *)in_header;
+            VkPhysicalDeviceDepthClipEnableFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->depthClipEnable = in->depthClipEnable;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT:
+        {
+            const VkPhysicalDeviceBufferAddressFeaturesEXT *in = (const VkPhysicalDeviceBufferAddressFeaturesEXT *)in_header;
+            VkPhysicalDeviceBufferAddressFeaturesEXT *out;
+
+            if (!(out = heap_alloc(sizeof(*out)))) goto out_of_memory;
+
+            out->sType = in->sType;
+            out->pNext = NULL;
+            out->bufferDeviceAddress = in->bufferDeviceAddress;
+            out->bufferDeviceAddressCaptureReplay = in->bufferDeviceAddressCaptureReplay;
+            out->bufferDeviceAddressMultiDevice = in->bufferDeviceAddressMultiDevice;
+
+            out_header->pNext = (VkBaseOutStructure *)out;
+            out_header = out_header->pNext;
+            break;
+        }
+
+        default:
+            FIXME("Application requested a linked structure of type %u.\n", in_header->sType);
+        }
+    }
+
+    return VK_SUCCESS;
+
+out_of_memory:
+    free_VkDeviceCreateInfo_struct_chain(out_struct);
+    return VK_ERROR_OUT_OF_HOST_MEMORY;
+}
+
+void free_VkDeviceCreateInfo_struct_chain(VkDeviceCreateInfo *s)
+{
+    VkBaseOutStructure *header = (void *)s->pNext;
+
+    while (header)
+    {
+        void *prev = header;
+        header = header->pNext;
+        heap_free(prev);
+    }
+
+    s->pNext = NULL;
+}
+
 VkResult convert_VkInstanceCreateInfo_struct_chain(const void *pNext, VkInstanceCreateInfo *out_struct)
 {
     VkBaseOutStructure *out_header = (VkBaseOutStructure *)out_struct;
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 3b8a93176abd..5da9aa9c4cae 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -765,6 +765,8 @@ typedef struct VkCopyDescriptorSet_host
 } VkCopyDescriptorSet_host;
 
 
+VkResult convert_VkDeviceCreateInfo_struct_chain(const void *pNext, VkDeviceCreateInfo *out_struct) DECLSPEC_HIDDEN;
+void free_VkDeviceCreateInfo_struct_chain(VkDeviceCreateInfo *s) DECLSPEC_HIDDEN;
 VkResult convert_VkInstanceCreateInfo_struct_chain(const void *pNext, VkInstanceCreateInfo *out_struct) DECLSPEC_HIDDEN;
 void free_VkInstanceCreateInfo_struct_chain(VkInstanceCreateInfo *s) DECLSPEC_HIDDEN;
 
-- 
2.21.0




More information about the wine-devel mailing list