diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index eb68a7be598..af376576268 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 259d7d18e7c..725bdf019e2 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; + } - dst->pNext = NULL; - dst_header = (VkBaseOutStructure *)dst; - for (header = src->pNext; header; header = header->pNext) + /* 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; + + if (!(physical_devices = heap_calloc(group_info->physicalDeviceCount, sizeof(*physical_devices)))) { - 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); - } + free_VkDeviceCreateInfo_struct_chain(dst); + return VK_ERROR_OUT_OF_HOST_MEMORY; } + for (i = 0; i < group_info->physicalDeviceCount; ++i) + { + 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 2f0cc6218e2..fc41fb00e33 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 3b8a93176ab..5da9aa9c4ca 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;