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.
From: Jacek Caban jacek@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;
From: Jacek Caban jacek@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")
From: Jacek Caban jacek@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)
From: Jacek Caban jacek@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)
From: Jacek Caban jacek@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; }
From: Jacek Caban jacek@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);
From: Jacek Caban jacek@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; };
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.
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).
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.
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.
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?
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.
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.
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`.