[PATCH v2 0/7] MR5128: winevulkan: Use VK_EXT_map_memory_placed for memory mapping on wow64.
With the new extension, we may implement wow64 correctly, without `VK_EXT_external_memory_host` hacks. This is both more correct and more performant (essentially eliminating Vulkan wow64 performance penalty). -- v2: winevulkan: Use VK_EXT_map_memory_placed for memory mapping on wow64. winevulkan: Add support for VK_EXT_map_memory_placed. winevulkan: Refactor extra extensions handling in wine_vk_device_convert_create_info. winevulkan: Use handle map for memory objects. winevulkan: Rename wine_device_memory mapping to vm_map. https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
From: Jacek Caban <jacek(a)codeweavers.com> The new spec uses length attribute for some static arrays. Change is_dynamic_array to account account for that. Eventually we could use the new information to improve conversion thunks. --- dlls/winevulkan/make_vulkan | 4 +- dlls/winevulkan/vulkan_thunks.c | 193 ++++++++++++++++++++++++++++---- dlls/winevulkan/winevulkan.json | 2 +- include/wine/vulkan.h | 55 ++++++++- 4 files changed, 228 insertions(+), 26 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index c98ce300be6..acb8ecbe3f6 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -64,7 +64,7 @@ from enum import Enum LOGGER = logging.Logger("vulkan") LOGGER.addHandler(logging.StreamHandler()) -VK_XML_VERSION = "1.3.277" +VK_XML_VERSION = "1.3.278" WINE_VK_VERSION = (1, 3) # Filenames to create. @@ -1316,7 +1316,7 @@ class VkVariable(object): Vulkan uses this for dynamically sized arrays for which there is a 'count' parameter. """ - return self.dyn_array_len is not None + return self.dyn_array_len is not None and self.array_len is None def is_static_array(self): """ Returns if the member is an array. diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index ce61f5cc9cf..a6af0d2f5da 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -3297,6 +3297,22 @@ typedef struct VkPhysicalDeviceShaderQuadControlFeaturesKHR32 VkBool32 shaderQuadControl; } VkPhysicalDeviceShaderQuadControlFeaturesKHR32; +typedef struct VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV32 +{ + VkStructureType sType; + PTR32 pNext; + VkBool32 shaderFloat16VectorAtomics; +} VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV32; + +typedef struct VkPhysicalDeviceMapMemoryPlacedFeaturesEXT32 +{ + VkStructureType sType; + PTR32 pNext; + VkBool32 memoryMapPlaced; + VkBool32 memoryMapRangePlaced; + VkBool32 memoryUnmapReserve; +} VkPhysicalDeviceMapMemoryPlacedFeaturesEXT32; + typedef struct VkDeviceCreateInfo32 { VkStructureType sType; @@ -6385,6 +6401,13 @@ typedef struct VkPhysicalDeviceRenderPassStripedPropertiesARM32 uint32_t maxRenderPassStripes; } VkPhysicalDeviceRenderPassStripedPropertiesARM32; +typedef struct VkPhysicalDeviceMapMemoryPlacedPropertiesEXT32 +{ + VkStructureType sType; + PTR32 pNext; + VkDeviceSize DECLSPEC_ALIGN(8) minPlacedMemoryMapAlignment; +} VkPhysicalDeviceMapMemoryPlacedPropertiesEXT32; + typedef struct VkPhysicalDeviceProperties232 { VkStructureType sType; @@ -6649,6 +6672,13 @@ typedef struct VkLatencySleepInfoNV32 uint64_t DECLSPEC_ALIGN(8) value; } VkLatencySleepInfoNV32; +typedef struct VkMemoryMapPlacedInfoEXT32 +{ + VkStructureType sType; + PTR32 pNext; + PTR32 pPlacedAddress; +} VkMemoryMapPlacedInfoEXT32; + typedef struct VkMemoryMapInfoKHR32 { VkStructureType sType; @@ -13608,6 +13638,30 @@ static inline void convert_VkDeviceCreateInfo_win64_to_host(struct conversion_co out_header = (void *)out_ext; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV: + { + VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV *in_ext = (const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV; + out_ext->pNext = NULL; + out_ext->shaderFloat16VectorAtomics = in_ext->shaderFloat16VectorAtomics; + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT: + { + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *in_ext = (const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; + out_ext->pNext = NULL; + out_ext->memoryMapPlaced = in_ext->memoryMapPlaced; + out_ext->memoryMapRangePlaced = in_ext->memoryMapRangePlaced; + out_ext->memoryUnmapReserve = in_ext->memoryUnmapReserve; + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } default: FIXME("Unhandled sType %u.\n", in_header->sType); break; @@ -15867,6 +15921,30 @@ static inline void convert_VkDeviceCreateInfo_win32_to_host(struct conversion_co out_header = (void *)out_ext; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV: + { + VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV32 *in_ext = (const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV32 *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV; + out_ext->pNext = NULL; + out_ext->shaderFloat16VectorAtomics = in_ext->shaderFloat16VectorAtomics; + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT: + { + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT32 *in_ext = (const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT32 *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; + out_ext->pNext = NULL; + out_ext->memoryMapPlaced = in_ext->memoryMapPlaced; + out_ext->memoryMapRangePlaced = in_ext->memoryMapRangePlaced; + out_ext->memoryUnmapReserve = in_ext->memoryUnmapReserve; + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } default: FIXME("Unhandled sType %u.\n", in_header->sType); break; @@ -20699,20 +20777,6 @@ static inline void convert_VkLatencyTimingsFrameReportNV_win32_to_host(const VkL out->sType = in->sType; out->pNext = NULL; - out->presentID = in->presentID; - out->inputSampleTimeUs = in->inputSampleTimeUs; - out->simStartTimeUs = in->simStartTimeUs; - out->simEndTimeUs = in->simEndTimeUs; - out->renderSubmitStartTimeUs = in->renderSubmitStartTimeUs; - out->renderSubmitEndTimeUs = in->renderSubmitEndTimeUs; - out->presentStartTimeUs = in->presentStartTimeUs; - out->presentEndTimeUs = in->presentEndTimeUs; - out->driverStartTimeUs = in->driverStartTimeUs; - out->driverEndTimeUs = in->driverEndTimeUs; - out->osRenderQueueStartTimeUs = in->osRenderQueueStartTimeUs; - out->osRenderQueueEndTimeUs = in->osRenderQueueEndTimeUs; - out->gpuRenderStartTimeUs = in->gpuRenderStartTimeUs; - out->gpuRenderEndTimeUs = in->gpuRenderEndTimeUs; if (in->pNext) FIXME("Unexpected pNext\n"); } @@ -23266,6 +23330,30 @@ static inline void convert_VkPhysicalDeviceFeatures2_win32_to_host(struct conver out_header = (void *)out_ext; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV: + { + VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV32 *in_ext = (const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV32 *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV; + out_ext->pNext = NULL; + out_ext->shaderFloat16VectorAtomics = in_ext->shaderFloat16VectorAtomics; + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT: + { + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT32 *in_ext = (const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT32 *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; + out_ext->pNext = NULL; + out_ext->memoryMapPlaced = in_ext->memoryMapPlaced; + out_ext->memoryMapRangePlaced = in_ext->memoryMapRangePlaced; + out_ext->memoryUnmapReserve = in_ext->memoryUnmapReserve; + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } default: FIXME("Unhandled sType %u.\n", in_header->sType); break; @@ -25087,6 +25175,26 @@ static inline void convert_VkPhysicalDeviceFeatures2_host_to_win32(const VkPhysi out_header = (void *)out_ext; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV: + { + VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV32 *out_ext = find_next_struct32(out_header, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV); + const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV *in_ext = (const VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV; + out_ext->shaderFloat16VectorAtomics = in_ext->shaderFloat16VectorAtomics; + out_header = (void *)out_ext; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT: + { + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT32 *out_ext = find_next_struct32(out_header, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT); + const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *in_ext = (const VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; + out_ext->memoryMapPlaced = in_ext->memoryMapPlaced; + out_ext->memoryMapRangePlaced = in_ext->memoryMapRangePlaced; + out_ext->memoryUnmapReserve = in_ext->memoryUnmapReserve; + out_header = (void *)out_ext; + break; + } default: break; } @@ -26533,6 +26641,15 @@ static inline void convert_VkPhysicalDeviceProperties2_win32_to_host(struct conv out_header = (void *)out_ext; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT: + { + VkPhysicalDeviceMapMemoryPlacedPropertiesEXT *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT; + out_ext->pNext = NULL; + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } default: FIXME("Unhandled sType %u.\n", in_header->sType); break; @@ -27708,6 +27825,15 @@ static inline void convert_VkPhysicalDeviceProperties2_host_to_win32(const VkPhy out_header = (void *)out_ext; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT: + { + VkPhysicalDeviceMapMemoryPlacedPropertiesEXT32 *out_ext = find_next_struct32(out_header, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT); + const VkPhysicalDeviceMapMemoryPlacedPropertiesEXT *in_ext = (const VkPhysicalDeviceMapMemoryPlacedPropertiesEXT *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT; + out_ext->minPlacedMemoryMapAlignment = in_ext->minPlacedMemoryMapAlignment; + out_header = (void *)out_ext; + break; + } default: break; } @@ -27744,11 +27870,8 @@ static inline void convert_VkQueueFamilyProperties2_win32_to_host(struct convers case VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR: { VkQueueFamilyGlobalPriorityPropertiesKHR *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); - const VkQueueFamilyGlobalPriorityPropertiesKHR32 *in_ext = (const VkQueueFamilyGlobalPriorityPropertiesKHR32 *)in_header; out_ext->sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR; out_ext->pNext = NULL; - out_ext->priorityCount = in_ext->priorityCount; - memcpy(out_ext->priorities, in_ext->priorities, VK_MAX_GLOBAL_PRIORITY_SIZE_KHR * sizeof(VkQueueGlobalPriorityKHR)); out_header->pNext = (void *)out_ext; out_header = (void *)out_ext; break; @@ -28668,8 +28791,11 @@ static inline void convert_VkLatencySleepInfoNV_win32_to_host(const VkLatencySle FIXME("Unexpected pNext\n"); } -static inline void convert_VkMemoryMapInfoKHR_win32_to_unwrapped_host(const VkMemoryMapInfoKHR32 *in, VkMemoryMapInfoKHR *out) +static inline void convert_VkMemoryMapInfoKHR_win32_to_unwrapped_host(struct conversion_context *ctx, const VkMemoryMapInfoKHR32 *in, VkMemoryMapInfoKHR *out) { + const VkBaseInStructure32 *in_header; + VkBaseOutStructure *out_header = (void *)out; + if (!in) return; out->sType = in->sType; @@ -28678,8 +28804,27 @@ static inline void convert_VkMemoryMapInfoKHR_win32_to_unwrapped_host(const VkMe out->memory = in->memory; out->offset = in->offset; out->size = in->size; - if (in->pNext) - FIXME("Unexpected pNext\n"); + + for (in_header = UlongToPtr(in->pNext); in_header; in_header = UlongToPtr(in_header->pNext)) + { + switch (in_header->sType) + { + case VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT: + { + VkMemoryMapPlacedInfoEXT *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext)); + const VkMemoryMapPlacedInfoEXT32 *in_ext = (const VkMemoryMapPlacedInfoEXT32 *)in_header; + out_ext->sType = VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT; + out_ext->pNext = NULL; + out_ext->pPlacedAddress = (void *)UlongToPtr(in_ext->pPlacedAddress); + out_header->pNext = (void *)out_ext; + out_header = (void *)out_ext; + break; + } + default: + FIXME("Unhandled sType %u.\n", in_header->sType); + break; + } + } } #ifdef _WIN64 @@ -44751,11 +44896,15 @@ static NTSTATUS thunk32_vkMapMemory2KHR(void *args) VkResult result; } *params = args; VkMemoryMapInfoKHR pMemoryMapInfo_host; + struct conversion_context local_ctx; + struct conversion_context *ctx = &local_ctx; TRACE("%#x, %#x, %#x\n", params->device, params->pMemoryMapInfo, params->ppData); - convert_VkMemoryMapInfoKHR_win32_to_unwrapped_host((const VkMemoryMapInfoKHR32 *)UlongToPtr(params->pMemoryMapInfo), &pMemoryMapInfo_host); + init_conversion_context(ctx); + convert_VkMemoryMapInfoKHR_win32_to_unwrapped_host(ctx, (const VkMemoryMapInfoKHR32 *)UlongToPtr(params->pMemoryMapInfo), &pMemoryMapInfo_host); params->result = wine_vkMapMemory2KHR((VkDevice)UlongToPtr(params->device), &pMemoryMapInfo_host, (void **)UlongToPtr(params->ppData)); + free_conversion_context(ctx); return STATUS_SUCCESS; } @@ -46345,6 +46494,7 @@ static const char * const vk_device_extensions[] = "VK_EXT_legacy_dithering", "VK_EXT_line_rasterization", "VK_EXT_load_store_op_none", + "VK_EXT_map_memory_placed", "VK_EXT_memory_budget", "VK_EXT_memory_priority", "VK_EXT_mesh_shader", @@ -46530,6 +46680,7 @@ static const char * const vk_device_extensions[] = "VK_NV_representative_fragment_test", "VK_NV_sample_mask_override_coverage", "VK_NV_scissor_exclusive", + "VK_NV_shader_atomic_float16_vector", "VK_NV_shader_image_footprint", "VK_NV_shader_sm_builtins", "VK_NV_shader_subgroup_partitioned", diff --git a/dlls/winevulkan/winevulkan.json b/dlls/winevulkan/winevulkan.json index c6dc93ff0c1..3da205fa21d 100644 --- a/dlls/winevulkan/winevulkan.json +++ b/dlls/winevulkan/winevulkan.json @@ -2,6 +2,6 @@ "file_format_version": "1.0.0", "ICD": { "library_path": ".\\winevulkan.dll", - "api_version": "1.3.277" + "api_version": "1.3.278" } } diff --git a/include/wine/vulkan.h b/include/wine/vulkan.h index c07c576c01b..568bc36e405 100644 --- a/include/wine/vulkan.h +++ b/include/wine/vulkan.h @@ -415,6 +415,8 @@ #define VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME "VK_EXT_host_image_copy" #define VK_KHR_MAP_MEMORY_2_SPEC_VERSION 1 #define VK_KHR_MAP_MEMORY_2_EXTENSION_NAME "VK_KHR_map_memory2" +#define VK_EXT_MAP_MEMORY_PLACED_SPEC_VERSION 1 +#define VK_EXT_MAP_MEMORY_PLACED_EXTENSION_NAME "VK_EXT_map_memory_placed" #define VK_EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION 1 #define VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME "VK_EXT_shader_atomic_float2" #define VK_EXT_SURFACE_MAINTENANCE_1_SPEC_VERSION 1 @@ -669,6 +671,8 @@ #define VK_KHR_MAINTENANCE_6_EXTENSION_NAME "VK_KHR_maintenance6" #define VK_NV_DESCRIPTOR_POOL_OVERALLOCATION_SPEC_VERSION 1 #define VK_NV_DESCRIPTOR_POOL_OVERALLOCATION_EXTENSION_NAME "VK_NV_descriptor_pool_overallocation" +#define VK_NV_SHADER_ATOMIC_FLOAT16_VECTOR_SPEC_VERSION 1 +#define VK_NV_SHADER_ATOMIC_FLOAT16_VECTOR_EXTENSION_NAME "VK_NV_shader_atomic_float16_vector" #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 #define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" #define VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION 1 @@ -695,7 +699,7 @@ #define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0) #define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0) #define VKSC_API_VERSION_1_0 VK_MAKE_API_VERSION(VKSC_API_VARIANT, 1, 0, 0) -#define VK_HEADER_VERSION 277 +#define VK_HEADER_VERSION 278 #define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; #define VK_USE_64_BIT_PTR_DEFINES 0 @@ -2969,6 +2973,12 @@ typedef enum VkMemoryHeapFlagBits VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7fffffff, } VkMemoryHeapFlagBits; +typedef enum VkMemoryMapFlagBits +{ + VK_MEMORY_MAP_PLACED_BIT_EXT = 0x00000001, + VK_MEMORY_MAP_FLAG_BITS_MAX_ENUM = 0x7fffffff, +} VkMemoryMapFlagBits; + typedef enum VkMemoryOverallocationBehaviorAMD { VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0, @@ -2990,6 +3000,12 @@ typedef enum VkMemoryPropertyFlagBits VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7fffffff, } VkMemoryPropertyFlagBits; +typedef enum VkMemoryUnmapFlagBitsKHR +{ + VK_MEMORY_UNMAP_RESERVE_BIT_EXT = 0x00000001, + VK_MEMORY_UNMAP_FLAG_BITS_KHR_MAX_ENUM = 0x7fffffff, +} VkMemoryUnmapFlagBitsKHR; + typedef enum VkMicromapCreateFlagBitsEXT { VK_MICROMAP_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = 0x00000001, @@ -3785,7 +3801,7 @@ typedef enum VkResult VK_OPERATION_DEFERRED_KHR = 1000268002, VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, VK_PIPELINE_COMPILE_REQUIRED = 1000297000, - VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT = 1000482000, + VK_INCOMPATIBLE_SHADER_BINARY_EXT = 1000482000, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, @@ -3794,6 +3810,7 @@ typedef enum VkResult VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, + VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT = VK_INCOMPATIBLE_SHADER_BINARY_EXT, VK_RESULT_MAX_ENUM = 0x7fffffff, } VkResult; @@ -4453,6 +4470,9 @@ typedef enum VkStructureType VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT = 1000270009, VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR = 1000271000, VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR = 1000271001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT = 1000272000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT = 1000272001, + VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT = 1000272002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT = 1000274000, VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT = 1000274001, @@ -4748,6 +4768,7 @@ typedef enum VkStructureType VK_STRUCTURE_TYPE_SET_DESCRIPTOR_BUFFER_OFFSETS_INFO_EXT = 1000545007, VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_BUFFER_EMBEDDED_SAMPLERS_INFO_EXT = 1000545008, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV = 1000546000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV = 1000563000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, @@ -7153,6 +7174,13 @@ typedef struct VkMemoryMapInfoKHR VkDeviceSize WINE_VK_ALIGN(8) size; } VkMemoryMapInfoKHR; +typedef struct VkMemoryMapPlacedInfoEXT +{ + VkStructureType sType; + const void *pNext; + void *pPlacedAddress; +} VkMemoryMapPlacedInfoEXT; + typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { VkStructureType sType; @@ -8789,6 +8817,22 @@ typedef struct VkPhysicalDeviceMaintenance6PropertiesKHR VkBool32 fragmentShadingRateClampCombinerInputs; } VkPhysicalDeviceMaintenance6PropertiesKHR; +typedef struct VkPhysicalDeviceMapMemoryPlacedFeaturesEXT +{ + VkStructureType sType; + void *pNext; + VkBool32 memoryMapPlaced; + VkBool32 memoryMapRangePlaced; + VkBool32 memoryUnmapReserve; +} VkPhysicalDeviceMapMemoryPlacedFeaturesEXT; + +typedef struct VkPhysicalDeviceMapMemoryPlacedPropertiesEXT +{ + VkStructureType sType; + void *pNext; + VkDeviceSize WINE_VK_ALIGN(8) minPlacedMemoryMapAlignment; +} VkPhysicalDeviceMapMemoryPlacedPropertiesEXT; + typedef struct VkPhysicalDeviceMemoryBudgetPropertiesEXT { VkStructureType sType; @@ -9421,6 +9465,13 @@ typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures } VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures; typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR; +typedef struct VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV +{ + VkStructureType sType; + void *pNext; + VkBool32 shaderFloat16VectorAtomics; +} VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV; + typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { VkStructureType sType; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
From: Jacek Caban <jacek(a)codeweavers.com> --- dlls/winevulkan/make_vulkan | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index acb8ecbe3f6..97edd5625bc 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -2032,14 +2032,11 @@ class VkStruct(Sequence): # Those structs seem to be broken in spec, they are specified as # returned only, but documented as input structs. - if name in ["VkSubpassShadingPipelineCreateInfoHUAWEI", - "VkPipelineShaderStageRequiredSubgroupSizeCreateInfo"]: + if name in ["VkPipelineShaderStageRequiredSubgroupSizeCreateInfo"]: returnedonly = False # Those structs don't have returnedonly in spec, but they could (should?). - if name in ["VkSurfaceCapabilitiesPresentBarrierNV", - "VkCooperativeMatrixPropertiesNV", - "VkPerformanceValueINTEL"]: + if name in ["VkSurfaceCapabilitiesPresentBarrierNV"]: returnedonly = True structextends = struct.attrib.get("structextends") -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
From: Jacek Caban <jacek(a)codeweavers.com> To avoid conflict with handle mapping macros. --- dlls/winevulkan/vulkan.c | 12 ++++++------ dlls/winevulkan/vulkan_private.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 9123e65da4c..5b822b914e7 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -1683,7 +1683,7 @@ VkResult wine_vkAllocateMemory(VkDevice handle, const VkMemoryAllocateInfo *allo return result; } - memory->mapping = mapping; + memory->vm_map = mapping; *ret = (VkDeviceMemory)(uintptr_t)memory; return VK_SUCCESS; } @@ -1699,10 +1699,10 @@ void wine_vkFreeMemory(VkDevice handle, VkDeviceMemory memory_handle, const VkAl device->funcs.p_vkFreeMemory(device->host_device, memory->host_memory, NULL); - if (memory->mapping) + if (memory->vm_map) { SIZE_T alloc_size = 0; - NtFreeVirtualMemory(GetCurrentProcess(), &memory->mapping, &alloc_size, MEM_RELEASE); + NtFreeVirtualMemory(GetCurrentProcess(), &memory->vm_map, &alloc_size, MEM_RELEASE); } free(memory); @@ -1731,9 +1731,9 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf VkResult result; info.memory = memory->host_memory; - if (memory->mapping) + if (memory->vm_map) { - *data = (char *)memory->mapping + info.offset; + *data = (char *)memory->vm_map + info.offset; TRACE("returning %p\n", *data); return VK_SUCCESS; } @@ -1779,7 +1779,7 @@ VkResult wine_vkUnmapMemory2KHR(VkDevice handle, const VkMemoryUnmapInfoKHR *unm struct wine_device_memory *memory = wine_device_memory_from_handle(unmap_info->memory); VkMemoryUnmapInfoKHR info; - if (memory->mapping) + if (memory->vm_map) return VK_SUCCESS; if (!device->funcs.p_vkUnmapMemory2KHR) diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 4e4d665299f..8ef065ac514 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -175,7 +175,7 @@ static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool hand struct wine_device_memory { VkDeviceMemory host_memory; - void *mapping; + void *vm_map; }; static inline struct wine_device_memory *wine_device_memory_from_handle(VkDeviceMemory handle) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
From: Jacek Caban <jacek(a)codeweavers.com> --- dlls/winevulkan/vulkan.c | 2 ++ dlls/winevulkan/vulkan_private.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 5b822b914e7..9f2fd630168 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -1683,6 +1683,7 @@ VkResult wine_vkAllocateMemory(VkDevice handle, const VkMemoryAllocateInfo *allo return result; } + WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, memory, memory->host_memory, memory); memory->vm_map = mapping; *ret = (VkDeviceMemory)(uintptr_t)memory; return VK_SUCCESS; @@ -1697,6 +1698,7 @@ void wine_vkFreeMemory(VkDevice handle, VkDeviceMemory memory_handle, const VkAl return; memory = wine_device_memory_from_handle(memory_handle); + WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, memory); device->funcs.p_vkFreeMemory(device->host_device, memory->host_memory, NULL); if (memory->vm_map) diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 8ef065ac514..fd5d58870cc 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -176,6 +176,8 @@ struct wine_device_memory { VkDeviceMemory host_memory; void *vm_map; + + struct wine_vk_mapping mapping; }; static inline struct wine_device_memory *wine_device_memory_from_handle(VkDeviceMemory handle) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
From: Jacek Caban <jacek(a)codeweavers.com> --- dlls/winevulkan/vulkan.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 9f2fd630168..baac3cd8683 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -391,10 +391,21 @@ static void wine_vk_device_get_queues(struct wine_device *device, } } +static const char *find_extension(const char *const *extensions, uint32_t count, const char *ext) +{ + while (count--) + { + if (!strcmp(extensions[count], ext)) + return extensions[count]; + } + return NULL; +} + static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_dev, struct conversion_context *ctx, const VkDeviceCreateInfo *src, VkDeviceCreateInfo *dst) { - unsigned int i; + const char *extra_extensions[2], * const*extensions = src->ppEnabledExtensionNames; + unsigned int i, extra_count = 0, extensions_count = src->enabledExtensionCount; *dst = *src; @@ -402,10 +413,10 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de dst->enabledLayerCount = 0; dst->ppEnabledLayerNames = NULL; - TRACE("Enabled %u extensions.\n", dst->enabledExtensionCount); - for (i = 0; i < dst->enabledExtensionCount; i++) + TRACE("Enabled %u extensions.\n", extensions_count); + for (i = 0; i < extensions_count; i++) { - const char *extension_name = dst->ppEnabledExtensionNames[i]; + const char *extension_name = extensions[i]; TRACE("Extension %u: %s.\n", i, debugstr_a(extension_name)); if (!wine_vk_device_extension_supported(extension_name)) { @@ -415,15 +426,21 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de } if (phys_dev->external_memory_align) + { + if (!find_extension(extensions, extensions_count, "VK_KHR_external_memory")) + extra_extensions[extra_count++] = "VK_KHR_external_memory"; + if (!find_extension(extensions, extensions_count, "VK_EXT_external_memory_host")) + extra_extensions[extra_count++] = "VK_EXT_external_memory_host"; + } + + if (extra_count) { const char **new_extensions; - new_extensions = conversion_context_alloc(ctx, (dst->enabledExtensionCount + 2) * - sizeof(*dst->ppEnabledExtensionNames)); - memcpy(new_extensions, src->ppEnabledExtensionNames, - dst->enabledExtensionCount * sizeof(*dst->ppEnabledExtensionNames)); - new_extensions[dst->enabledExtensionCount++] = "VK_KHR_external_memory"; - new_extensions[dst->enabledExtensionCount++] = "VK_EXT_external_memory_host"; + dst->enabledExtensionCount += extra_count; + new_extensions = conversion_context_alloc(ctx, dst->enabledExtensionCount * sizeof(*new_extensions)); + memcpy(new_extensions, extensions, extensions_count * sizeof(*new_extensions)); + memcpy(new_extensions + extensions_count, extra_extensions, extra_count * sizeof(*new_extensions)); dst->ppEnabledExtensionNames = new_extensions; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
From: Jacek Caban <jacek(a)codeweavers.com> --- dlls/winevulkan/make_vulkan | 1 + dlls/winevulkan/vulkan.c | 81 +++++++++++++++++++++++++++++--- dlls/winevulkan/vulkan_private.h | 2 + dlls/winevulkan/vulkan_thunks.c | 4 +- dlls/winevulkan/vulkan_thunks.h | 1 + 5 files changed, 81 insertions(+), 8 deletions(-) diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 97edd5625bc..9d66bb9f606 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -257,6 +257,7 @@ MANUAL_UNIX_THUNKS = { "vkGetPhysicalDeviceExternalFencePropertiesKHR", "vkGetPhysicalDeviceExternalSemaphoreProperties", "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR", + "vkGetPhysicalDeviceFeatures2KHR", "vkGetPhysicalDeviceImageFormatProperties2", "vkGetPhysicalDeviceImageFormatProperties2KHR", "vkGetPhysicalDeviceSurfaceCapabilities2KHR", diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index baac3cd8683..f875111d0d5 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -406,6 +406,7 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de { const char *extra_extensions[2], * const*extensions = src->ppEnabledExtensionNames; unsigned int i, extra_count = 0, extensions_count = src->enabledExtensionCount; + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *map_placed_features; *dst = *src; @@ -425,6 +426,8 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de } } + map_placed_features = find_next_struct(dst->pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT); + if (phys_dev->external_memory_align) { if (!find_extension(extensions, extensions_count, "VK_KHR_external_memory")) @@ -444,6 +447,15 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de dst->ppEnabledExtensionNames = new_extensions; } + /* If memoryMapPlaced is enabled, we need also memoryUnmapReserve to support unmapping. */ + if (map_placed_features) + { + if (map_placed_features->memoryMapPlaced) + map_placed_features->memoryUnmapReserve = VK_TRUE; + if (map_placed_features->memoryMapRangePlaced) + return VK_ERROR_FEATURE_NOT_PRESENT; + } + return VK_SUCCESS; } @@ -1218,6 +1230,23 @@ VkResult wine_vkEnumeratePhysicalDeviceGroupsKHR(VkInstance handle, uint32_t *co instance->funcs.p_vkEnumeratePhysicalDeviceGroupsKHR, count, properties); } +void wine_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice phys_dev_handle, VkPhysicalDeviceFeatures2 *features) +{ + struct wine_phys_dev *phys_dev = wine_phys_dev_from_handle(phys_dev_handle); + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT *map_placed_features; + + phys_dev->instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(phys_dev->host_physical_device, features); + + map_placed_features = find_next_struct(features->pNext, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT); + if (map_placed_features) + { + if (!map_placed_features->memoryUnmapReserve) + map_placed_features->memoryMapPlaced = VK_FALSE; + map_placed_features->memoryMapRangePlaced = VK_FALSE; + } +} + void wine_vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice phys_dev, const VkPhysicalDeviceExternalFenceInfo *fence_info, VkExternalFenceProperties *properties) @@ -1701,7 +1730,9 @@ VkResult wine_vkAllocateMemory(VkDevice handle, const VkMemoryAllocateInfo *allo } WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, memory, memory->host_memory, memory); + memory->size = info.allocationSize; memory->vm_map = mapping; + memory->preserve_map = FALSE; *ret = (VkDeviceMemory)(uintptr_t)memory; return VK_SUCCESS; } @@ -1715,10 +1746,21 @@ void wine_vkFreeMemory(VkDevice handle, VkDeviceMemory memory_handle, const VkAl return; memory = wine_device_memory_from_handle(memory_handle); + if (memory->vm_map && !device->phys_dev->external_memory_align) + { + const VkMemoryUnmapInfoKHR info = + { + .sType = VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR, + .memory = memory->host_memory, + .flags = VK_MEMORY_UNMAP_RESERVE_BIT_EXT, + }; + device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); + } + WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, memory); device->funcs.p_vkFreeMemory(device->host_device, memory->host_memory, NULL); - if (memory->vm_map) + if (memory->vm_map && !memory->preserve_map) { SIZE_T alloc_size = 0; NtFreeVirtualMemory(GetCurrentProcess(), &memory->vm_map, &alloc_size, MEM_RELEASE); @@ -1747,16 +1789,21 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf struct wine_device *device = wine_device_from_handle(handle); struct wine_device_memory *memory = wine_device_memory_from_handle(map_info->memory); VkMemoryMapInfoKHR info = *map_info; + VkMemoryMapPlacedInfoEXT *placed_info_arg; VkResult result; - info.memory = memory->host_memory; if (memory->vm_map) { - *data = (char *)memory->vm_map + info.offset; + *data = (char *)memory->vm_map + map_info->offset; TRACE("returning %p\n", *data); return VK_SUCCESS; } + info = *map_info; + info.memory = memory->host_memory; + + placed_info_arg = find_next_struct(info.pNext, VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT); + if (device->funcs.p_vkMapMemory2KHR) { result = device->funcs.p_vkMapMemory2KHR(device->host_device, &info, data); @@ -1768,6 +1815,12 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf info.size, info.flags, data); } + if (info.flags & VK_MEMORY_MAP_PLACED_BIT_EXT) + { + memory->vm_map = placed_info_arg->pPlacedAddress; + memory->preserve_map = TRUE; + } + #ifdef _WIN64 if (NtCurrentTeb()->WowTebOffset && result == VK_SUCCESS && (UINT_PTR)*data >> 32) { @@ -1797,20 +1850,36 @@ VkResult wine_vkUnmapMemory2KHR(VkDevice handle, const VkMemoryUnmapInfoKHR *unm struct wine_device *device = wine_device_from_handle(handle); struct wine_device_memory *memory = wine_device_memory_from_handle(unmap_info->memory); VkMemoryUnmapInfoKHR info; + VkResult result; - if (memory->vm_map) + if (memory->vm_map && device->phys_dev->external_memory_align) return VK_SUCCESS; if (!device->funcs.p_vkUnmapMemory2KHR) { - assert(!unmap_info->pNext); + assert(!unmap_info->pNext && !memory->vm_map); device->funcs.p_vkUnmapMemory(device->host_device, memory->host_memory); return VK_SUCCESS; } info = *unmap_info; info.memory = memory->host_memory; - return device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); + if (memory->vm_map) + info.flags |= VK_MEMORY_UNMAP_RESERVE_BIT_EXT; + + result = device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); + + if (result == VK_SUCCESS && memory->vm_map) + { + if (!(unmap_info->flags & VK_MEMORY_UNMAP_RESERVE_BIT_EXT)) + { + SIZE_T size = memory->size; + NtFreeVirtualMemory(GetCurrentProcess(), &memory->vm_map, &size, MEM_RELEASE); + } + memory->vm_map = NULL; + memory->preserve_map = FALSE; + } + return result; } VkResult wine_vkCreateBuffer(VkDevice handle, const VkBufferCreateInfo *create_info, diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index fd5d58870cc..dde0af26ec7 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -175,7 +175,9 @@ static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool hand struct wine_device_memory { VkDeviceMemory host_memory; + VkDeviceSize size; void *vm_map; + BOOL preserve_map; struct wine_vk_mapping mapping; }; diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c index a6af0d2f5da..da5395ef06f 100644 --- a/dlls/winevulkan/vulkan_thunks.c +++ b/dlls/winevulkan/vulkan_thunks.c @@ -42777,7 +42777,7 @@ static NTSTATUS thunk64_vkGetPhysicalDeviceFeatures2KHR(void *args) TRACE("%p, %p\n", params->physicalDevice, params->pFeatures); - wine_phys_dev_from_handle(params->physicalDevice)->instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(wine_phys_dev_from_handle(params->physicalDevice)->host_physical_device, params->pFeatures); + wine_vkGetPhysicalDeviceFeatures2KHR(params->physicalDevice, params->pFeatures); return STATUS_SUCCESS; } #endif /* _WIN64 */ @@ -42797,7 +42797,7 @@ static NTSTATUS thunk32_vkGetPhysicalDeviceFeatures2KHR(void *args) init_conversion_context(ctx); convert_VkPhysicalDeviceFeatures2_win32_to_host(ctx, (VkPhysicalDeviceFeatures232 *)UlongToPtr(params->pFeatures), &pFeatures_host); - wine_phys_dev_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(wine_phys_dev_from_handle((VkPhysicalDevice)UlongToPtr(params->physicalDevice))->host_physical_device, &pFeatures_host); + wine_vkGetPhysicalDeviceFeatures2KHR((VkPhysicalDevice)UlongToPtr(params->physicalDevice), &pFeatures_host); convert_VkPhysicalDeviceFeatures2_host_to_win32(&pFeatures_host, (VkPhysicalDeviceFeatures232 *)UlongToPtr(params->pFeatures)); free_conversion_context(ctx); return STATUS_SUCCESS; diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h index 2c2712291c1..19bca560ef8 100644 --- a/dlls/winevulkan/vulkan_thunks.h +++ b/dlls/winevulkan/vulkan_thunks.h @@ -56,6 +56,7 @@ void wine_vkGetPhysicalDeviceExternalFenceProperties(VkPhysicalDevice physicalDe void wine_vkGetPhysicalDeviceExternalFencePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo, VkExternalFenceProperties *pExternalFenceProperties); void wine_vkGetPhysicalDeviceExternalSemaphoreProperties(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); void wine_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo, VkExternalSemaphoreProperties *pExternalSemaphoreProperties); +void wine_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 *pFeatures); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); VkResult wine_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties); VkResult wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
From: Jacek Caban <jacek(a)codeweavers.com> --- dlls/winevulkan/vulkan.c | 98 ++++++++++++++++++++++++++++++-- dlls/winevulkan/vulkan_private.h | 1 + 2 files changed, 94 insertions(+), 5 deletions(-) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index f875111d0d5..4f1980c0ac0 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -223,6 +223,7 @@ static void wine_vk_physical_device_free(struct wine_phys_dev *phys_dev) static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance *instance, VkPhysicalDevice phys_dev, VkPhysicalDevice handle) { + BOOL have_memory_placed = FALSE, have_map_memory2 = FALSE; struct wine_phys_dev *object; uint32_t num_host_properties, num_properties = 0; VkExtensionProperties *host_properties = NULL; @@ -281,6 +282,10 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance } if (!strcmp(host_properties[i].extensionName, "VK_EXT_external_memory_host")) have_external_memory_host = TRUE; + else if (!strcmp(host_properties[i].extensionName, "VK_EXT_map_memory_placed")) + have_memory_placed = TRUE; + else if (!strcmp(host_properties[i].extensionName, "VK_KHR_map_memory2")) + have_map_memory2 = TRUE; } TRACE("Host supported extensions %u, Wine supported extensions %u\n", num_host_properties, num_properties); @@ -301,7 +306,38 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance } object->extension_count = num_properties; - if (use_external_memory() && have_external_memory_host) + if (zero_bits && have_memory_placed && have_map_memory2) + { + VkPhysicalDeviceMapMemoryPlacedFeaturesEXT map_placed_feature = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT, + }; + VkPhysicalDeviceFeatures2 features = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + .pNext = &map_placed_feature, + }; + + instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(phys_dev, &features); + if (map_placed_feature.memoryMapPlaced && map_placed_feature.memoryUnmapReserve) + { + VkPhysicalDeviceMapMemoryPlacedPropertiesEXT map_placed_props = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_PROPERTIES_EXT, + }; + VkPhysicalDeviceProperties2 props = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + .pNext = &map_placed_props, + }; + + instance->funcs.p_vkGetPhysicalDeviceProperties2(phys_dev, &props); + object->map_placed_align = map_placed_props.minPlacedMemoryMapAlignment; + TRACE("map_placed_align %u\n", object->map_placed_align); + } + } + + if (zero_bits && have_external_memory_host && !object->map_placed_align) { VkPhysicalDeviceExternalMemoryHostPropertiesEXT host_mem_props = { @@ -428,7 +464,25 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de map_placed_features = find_next_struct(dst->pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT); - if (phys_dev->external_memory_align) + if (phys_dev->map_placed_align) + { + if (!find_extension(extensions, extensions_count, "VK_EXT_map_memory_placed")) + extra_extensions[extra_count++] = "VK_EXT_map_memory_placed"; + if (!find_extension(extensions, extensions_count, "VK_KHR_map_memory2")) + extra_extensions[extra_count++] = "VK_KHR_map_memory2"; + + if (!map_placed_features) + { + map_placed_features = conversion_context_alloc(ctx, sizeof(*map_placed_features)); + map_placed_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAP_MEMORY_PLACED_FEATURES_EXT; + map_placed_features->pNext = (void *)dst->pNext; + dst->pNext = map_placed_features; + } + map_placed_features->memoryMapPlaced = VK_TRUE; + map_placed_features->memoryMapRangePlaced = VK_FALSE; + map_placed_features->memoryUnmapReserve = VK_TRUE; + } + else if (phys_dev->external_memory_align) { if (!find_extension(extensions, extensions_count, "VK_KHR_external_memory")) extra_extensions[extra_count++] = "VK_KHR_external_memory"; @@ -1788,8 +1842,11 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf { struct wine_device *device = wine_device_from_handle(handle); struct wine_device_memory *memory = wine_device_memory_from_handle(map_info->memory); - VkMemoryMapInfoKHR info = *map_info; - VkMemoryMapPlacedInfoEXT *placed_info_arg; + VkMemoryMapInfoKHR info; + VkMemoryMapPlacedInfoEXT *placed_info_arg, placed_info = + { + .sType = VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT, + }; VkResult result; if (memory->vm_map) @@ -1803,6 +1860,24 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf info.memory = memory->host_memory; placed_info_arg = find_next_struct(info.pNext, VK_STRUCTURE_TYPE_MEMORY_MAP_PLACED_INFO_EXT); + if (device->phys_dev->map_placed_align && !placed_info_arg) + { + SIZE_T alloc_size = memory->size; + + placed_info_arg = &placed_info; + placed_info.pNext = info.pNext; + info.pNext = &placed_info; + info.offset = 0; + info.size = VK_WHOLE_SIZE; + info.flags |= VK_MEMORY_MAP_PLACED_BIT_EXT; + + if (NtAllocateVirtualMemory(GetCurrentProcess(), &placed_info.pPlacedAddress, zero_bits, &alloc_size, + MEM_RESERVE, PAGE_READWRITE)) + { + ERR("NtAllocateVirtualMemory failed\n"); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } if (device->funcs.p_vkMapMemory2KHR) { @@ -1815,7 +1890,20 @@ VkResult wine_vkMapMemory2KHR(VkDevice handle, const VkMemoryMapInfoKHR *map_inf info.size, info.flags, data); } - if (info.flags & VK_MEMORY_MAP_PLACED_BIT_EXT) + if (placed_info.pPlacedAddress) + { + if (result != VK_SUCCESS) + { + SIZE_T alloc_size = 0; + ERR("vkMapMemory2EXT failed: %d\n", result); + NtFreeVirtualMemory(GetCurrentProcess(), &placed_info.pPlacedAddress, &alloc_size, MEM_RELEASE); + return result; + } + memory->vm_map = placed_info.pPlacedAddress; + *data = (char *)memory->vm_map + map_info->offset; + TRACE("Using VK_EXT_map_memory_placed mapping %p\n", memory->vm_map); + } + else if (info.flags & VK_MEMORY_MAP_PLACED_BIT_EXT) { memory->vm_map = placed_info_arg->pPlacedAddress; memory->preserve_map = TRUE; diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index dde0af26ec7..de63fbf4ba6 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -130,6 +130,7 @@ struct wine_phys_dev uint32_t extension_count; uint32_t external_memory_align; + uint32_t map_placed_align; struct wine_vk_mapping mapping; }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5128
On Wed Feb 21 09:08:10 2024 +0000, Georg Lehmann wrote:
Do we need to anything special if the application uses placed map and doesn't reserve on unmap? The Vulkan driver will munmap, but is wine's allocator aware of that? It needs a bit more tweaking, we'd need store the memory to application-provided mapping and unmap it ourselves. A bit more care is also needed for reported features. I added it in the new version together with better features reporting.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62215
On Wed Feb 21 17:18:21 2024 +0000, Jacek Caban wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/5128/diffs?diff_id=100919&start_sha=fa067b02b0a8031df38138c63f263c0e8a786de7#561751f09a3d9e02a084f385e9182f0184b50581_469_469) Are you sure about that? I don't see it explicitly prohibited and it doesn't seem to cause problem in my testing. This code could use a bit more sharing between code paths, so I refactored it and avoided duplicates, but there is a similar thing in `wine_vk_instance_convert_create_info` (in which we probably want to make `VK_KHR_external_memory_capabilities` optional now).
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62216
On Wed Feb 21 17:18:22 2024 +0000, Jacek Caban wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/5128/diffs?diff_id=100919&start_sha=fa067b02b0a8031df38138c63f263c0e8a786de7#561751f09a3d9e02a084f385e9182f0184b50581_1681_1711) Yeah, it's probably not needed. We'd probably need it for ranged maps as otherwise we wouldn't be able to align range sizes, but it's not something we need to care about now.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62217
On Wed Feb 21 17:26:35 2024 +0000, Jacek Caban wrote:
Are you sure about that? I don't see it explicitly prohibited and it doesn't seem to cause problem in my testing. This code could use a bit more sharing between code paths, so I refactored it and avoided duplicates, but there is a similar thing in `wine_vk_instance_convert_create_info` (in which we probably want to make `VK_KHR_external_memory_capabilities` optional now). That comment was meant as a reply to duplicated extensions comment.
For `vk_is_available_device_function`, that's right (and that doesn't seem too problematic). I was thinking that ideally we'd just get rid of `vk_is_available_device_function`. We could store enabled extensions in VkDevice_T and implement `vkGetDeviceProcAddr` based on that, without any Unix calls. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62218
Not that it will likely come up, but as we're also allowing win32 clients to use this extension: - Would it make sense to make sure incoming pPlacedAddress belongs to a NT mapping? - Do we want to reset windows page protection back to '0' to match PROT_NONE resulting from VK_MEMORY_UNMAP_RESERVE_BIT_EXT? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62429
Are you sure about that? I don't see it explicitly prohibited and it doesn't seem to cause problem in my testing. This code could use a bit more sharing between code paths, so I refactored it and avoided duplicates, but there is a similar thing in `wine_vk_instance_convert_create_info` (in which we probably want to make `VK_KHR_external_memory_capabilities` optional now).
I thought I was sure, but I can't find anything in the spec either. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62670
On Wed Feb 21 17:35:01 2024 +0000, Jacek Caban wrote:
That comment was meant as a reply to duplicated extensions comment. For `vk_is_available_device_function`, that's right (and that doesn't seem too problematic). I was thinking that ideally we'd just get rid of `vk_is_available_device_function`. We could store enabled extensions in VkDevice_T and implement `vkGetDeviceProcAddr` based on that, without any Unix calls. Yeah we could get rid of it, I guess is shouldn't be too hard to copy what mesa does here.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62671
Georg Lehmann (@DadSchoorse) commented about dlls/winevulkan/make_vulkan:
LOGGER = logging.Logger("vulkan") LOGGER.addHandler(logging.StreamHandler())
-VK_XML_VERSION = "1.3.277" +VK_XML_VERSION = "1.3.278" I think now that you split implementing placed map and the spec version dumb, this commit should initially add `VK_EXT_map_memory_placed` to `UNSUPPORTED_EXTENSIONS`.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5128#note_62673
participants (4)
-
Derek Lesho (@dlesho) -
Georg Lehmann (@DadSchoorse) -
Jacek Caban -
Jacek Caban (@jacek)