diff --git a/ThunkLibs/libvulkan/Host.cpp b/ThunkLibs/libvulkan/Host.cpp index 591a0f2d2..e61b397da 100644 --- a/ThunkLibs/libvulkan/Host.cpp +++ b/ThunkLibs/libvulkan/Host.cpp @@ -16,7 +16,10 @@ $end_info$ #include #include +#include #include +#include +#include #include "thunkgen_host_libvulkan.inl" @@ -141,9 +144,7 @@ static VkResult FEXFN_IMPL(vkCreateInstance)(const VkInstanceCreateInfo* a_0, co VkInstance out; auto ret = LDR_PTR(vkCreateInstance)(vk_struct_base, nullptr, &out); - if (ret == VK_SUCCESS) { - *a_2.get_pointer() = to_guest(to_host_layout(out)); - } + *a_2.get_pointer() = to_guest(to_host_layout(out)); return ret; } @@ -151,9 +152,7 @@ static VkResult FEXFN_IMPL(vkCreateDevice)(VkPhysicalDevice a_0, const VkDeviceC guest_layout a_3) { VkDevice out; auto ret = LDR_PTR(vkCreateDevice)(a_0, a_1, nullptr, &out); - if (ret == VK_SUCCESS) { - *a_3.get_pointer() = to_guest(to_host_layout(out)); - } + *a_3.get_pointer() = to_guest(to_host_layout(out)); return ret; } @@ -193,6 +192,115 @@ static VkResult FEXFN_IMPL(vkCreateDebugUtilsMessengerEXT)(VkInstance_T* a_0, gu return LDR_PTR(vkCreateDebugUtilsMessengerEXT)(a_0, &overridden_callback, nullptr, a_3); } +#ifdef IS_32BIT_THUNK +VkResult fexfn_impl_libvulkan_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* count, guest_layout devices) { + if (!devices.get_pointer()) { + return fexldr_ptr_libvulkan_vkEnumeratePhysicalDevices(instance, count, nullptr); + } + + auto input_count = *count; + std::vector out(input_count); + auto ret = fexldr_ptr_libvulkan_vkEnumeratePhysicalDevices(instance, count, out.data()); + for (size_t i = 0; i < std::min(input_count, *count); ++i) { + devices.get_pointer()[i] = to_guest(to_host_layout(out[i])); + } + return ret; +} + +void fexfn_impl_libvulkan_vkGetDeviceQueue(VkDevice device, uint32_t family_index, uint32_t queue_index, guest_layout queue) { + VkQueue out; + (void*&)fexldr_ptr_libvulkan_vkGetDeviceQueue = (void*)LDR_PTR(vkGetDeviceProcAddr)(device, "vkGetDeviceQueue"); + fexldr_ptr_libvulkan_vkGetDeviceQueue(device, family_index, queue_index, &out); + *queue.get_pointer() = to_guest(to_host_layout(out)); +} + +VkResult fexfn_impl_libvulkan_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo* info, + guest_layout buffers) { + std::vector out(info->commandBufferCount); + (void*&)fexldr_ptr_libvulkan_vkAllocateCommandBuffers = (void*)LDR_PTR(vkGetDeviceProcAddr)(device, "vkAllocateCommandBuffers"); + auto ret = fexldr_ptr_libvulkan_vkAllocateCommandBuffers(device, info, out.data()); + if (ret == VK_SUCCESS) { + for (size_t i = 0; i < info->commandBufferCount; ++i) { + buffers.get_pointer()[i] = to_guest(to_host_layout(out[i])); + } + } + return ret; +} + +VkResult fexfn_impl_libvulkan_vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, + VkMemoryMapFlags flags, guest_layout data) { + host_layout host_data {}; + void* mapped; + (void*&)fexldr_ptr_libvulkan_vkMapMemory = (void*)LDR_PTR(vkGetDeviceProcAddr)(device, "vkMapMemory"); + auto ret = fexldr_ptr_libvulkan_vkMapMemory(device, memory, offset, size, flags, &mapped); + if (ret == VK_SUCCESS) { + host_data.data = mapped; + *data.get_pointer() = to_guest(host_data); + } + return ret; +} + +// Allocates storage on the heap that must be de-allocated using delete[] +template +std::span> RepackStructArray(uint32_t Count, const guest_layout GuestData) { + if (!GuestData.get_pointer() || Count == 0) { + return {}; + } + + auto HostData = new std::remove_cv_t[Count]; + for (size_t i = 0; i < Count; ++i) { + auto& GuestElement = (const guest_layout>&)GuestData.get_pointer()[i]; + auto Element = host_layout> {GuestElement}; + if constexpr (NeedsRepack) { + fex_apply_custom_repacking_entry(Element, GuestElement); + } + HostData[i] = Element.data; + } + return {HostData, Count}; +} + +void fexfn_impl_libvulkan_vkUpdateDescriptorSets(VkDevice device, unsigned int descriptorWriteCount, + guest_layout pDescriptorWrites, unsigned int descriptorCopyCount, + guest_layout pDescriptorCopies) { + + auto HostDescriptorWrites = RepackStructArray(descriptorWriteCount, pDescriptorWrites); + auto HostDescriptorCopies = RepackStructArray(descriptorCopyCount, pDescriptorCopies); + + (void*&)fexldr_ptr_libvulkan_vkUpdateDescriptorSets = (void*)LDR_PTR(vkGetDeviceProcAddr)(device, "vkUpdateDescriptorSets"); + fexldr_ptr_libvulkan_vkUpdateDescriptorSets(device, descriptorWriteCount, HostDescriptorWrites.data(), descriptorCopyCount, + HostDescriptorCopies.data()); + + delete[] HostDescriptorCopies.data(); + delete[] HostDescriptorWrites.data(); +} + +VkResult fexfn_impl_libvulkan_vkQueueSubmit(VkQueue queue, uint32_t submit_count, guest_layout submit_infos, VkFence fence) { + + auto HostSubmitInfos = RepackStructArray(submit_count, submit_infos); + auto ret = fexldr_ptr_libvulkan_vkQueueSubmit(queue, submit_count, HostSubmitInfos.data(), fence); + delete[] HostSubmitInfos.data(); + return ret; +} + +void fexfn_impl_libvulkan_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool, uint32_t num_buffers, + guest_layout buffers) { + + auto HostBuffers = RepackStructArray(num_buffers, buffers); + (void*&)fexldr_ptr_libvulkan_vkFreeCommandBuffers = (void*)LDR_PTR(vkGetDeviceProcAddr)(device, "vkFreeCommandBuffers"); + fexldr_ptr_libvulkan_vkFreeCommandBuffers(device, pool, num_buffers, HostBuffers.data()); + delete[] HostBuffers.data(); +} + +VkResult fexfn_impl_libvulkan_vkGetPipelineCacheData(VkDevice device, VkPipelineCache cache, guest_layout guest_data_size, void* data) { + size_t data_size = guest_data_size.get_pointer()->data; + (void*&)fexldr_ptr_libvulkan_vkGetPipelineCacheData = (void*)LDR_PTR(vkGetDeviceProcAddr)(device, "vkGetPipelineCacheData"); + auto ret = fexldr_ptr_libvulkan_vkGetPipelineCacheData(device, cache, &data_size, data); + *guest_data_size.get_pointer() = data_size; + return ret; +} + +#endif + static PFN_vkVoidFunction LookupCustomVulkanFunction(const char* a_1) { using namespace std::string_view_literals; @@ -206,6 +314,7 @@ static PFN_vkVoidFunction LookupCustomVulkanFunction(const char* a_1) { return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkAllocateMemory; } else if (a_1 == "vkFreeMemory"sv) { return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkFreeMemory; + // TODO: Review if 32-bit changes are needed } else if (a_1 == "vkAcquireXlibDisplayEXT"sv) { return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkAcquireXlibDisplayEXT; } else if (a_1 == "vkGetRandROutputDisplayEXT"sv) { @@ -214,6 +323,24 @@ static PFN_vkVoidFunction LookupCustomVulkanFunction(const char* a_1) { return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkGetPhysicalDeviceXcbPresentationSupportKHR; } else if (a_1 == "vkGetPhysicalDeviceXlibPresentationSupportKHR"sv) { return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkGetPhysicalDeviceXlibPresentationSupportKHR; +#ifdef IS_32BIT_THUNK + } else if (a_1 == "vkAllocateCommandBuffers"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkAllocateCommandBuffers; + } else if (a_1 == "vkEnumeratePhysicalDevices"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkEnumeratePhysicalDevices; + } else if (a_1 == "vkFreeCommandBuffers"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkFreeCommandBuffers; + } else if (a_1 == "vkGetDeviceQueue"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkGetDeviceQueue; + } else if (a_1 == "vkGetPipelineCacheData"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkGetPipelineCacheData; + } else if (a_1 == "vkMapMemory"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkMapMemory; + } else if (a_1 == "vkQueueSubmit"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkQueueSubmit; + } else if (a_1 == "vkUpdateDescriptorSets"sv) { + return (PFN_vkVoidFunction)fexfn_impl_libvulkan_vkUpdateDescriptorSets; +#endif } return nullptr; } @@ -265,4 +392,450 @@ static PFN_vkVoidFunction FEXFN_IMPL(vkGetInstanceProcAddr)(VkInstance a_0, cons return LDR_PTR(vkGetInstanceProcAddr)(a_0, a_1); } +#ifdef IS_32BIT_THUNK +template +static VkBaseOutStructure* convert(const guest_layout* source) { + // Using malloc here since no easily available type information is available at the time of destruction. + auto typed_source = reinterpret_cast*>(source); + auto child_mem = (char*)aligned_alloc(alignof(host_layout), sizeof(host_layout)); + auto child = new (child_mem) host_layout {*typed_source}; + + fex_custom_repack_entry(*child, *typed_source); + + return reinterpret_cast(&child->data); +} + +template +static void convert_to_guest(void* into, const VkBaseOutStructure* from) { + auto typed_into = reinterpret_cast*>(into); + auto oldNext = typed_into->data.pNext; // TODO: This assumes Vulkan never modifies pNext internally + *typed_into = to_guest(to_host_layout(*(Type*)from)); + typed_into->data.pNext = oldNext; + + fex_custom_repack_exit(*typed_into, to_host_layout(*(Type*)from)); +} + +template +inline constexpr std::pair*), void (*)(void*, const VkBaseOutStructure*)>> + converters = {TypeIndex, {convert, convert_to_guest}}; + +// NOTE: Not all Vulkan structures with pNext members are listed here. This is because excluding structs exclusively used as top-level entries is useful to detect repacking bugs. +static std::unordered_map*), void (*)(void*, const VkBaseOutStructure*)>> next_handlers { + converters, + converters, + converters, + converters, + converters, + converters, + converters, + converters, +}; + +static void default_fex_custom_repack_entry(VkBaseOutStructure& into, const guest_layout* from) { + if (!from->data.pNext.get_pointer()) { + into.pNext = nullptr; + return; + } + auto typed_source = reinterpret_cast*>(from->data.pNext.get_pointer()); + + auto next_handler = next_handlers.find(static_cast(typed_source->data.sType.data)); + if (next_handler == next_handlers.end()) { + fprintf(stderr, "ERROR: Unrecognized VkStructureType %u referenced by pNext\n", typed_source->data.sType.data); + std::abort(); + } + + into.pNext = next_handler->second.first(typed_source); +} + +template +void default_fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(*(VkBaseOutStructure*)&into.data, reinterpret_cast*>(&from)); +} + +static void default_fex_custom_repack_reverse(guest_layout& into, const VkBaseOutStructure* from) { + auto pNextHost = from->pNext; + if (!pNextHost) { + return; + } + + auto next_handler = next_handlers.find(static_cast(into.data.pNext.get_pointer()->data.sType.data)); + if (next_handler == next_handlers.end()) { + fprintf(stderr, "ERROR: Unrecognized VkStructureType %u referenced by pNext when converting to guest\n", from->sType); + std::abort(); + } + next_handler->second.second((void*)into.data.pNext.get_pointer(), from->pNext); + + free(pNextHost); +} + +// Default repacking functions that only traverses and repacks the pNext chain. +// If other members need to be repacked, use VULKAN_NONDEFAULT_CUSTOM_REPACK instead +#define VULKAN_DEFAULT_CUSTOM_REPACK(name) \ + void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { \ + default_fex_custom_repack_entry(reinterpret_cast(into.data), \ + &reinterpret_cast&>(from)); \ + } \ + \ + bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { \ + auto prev_next = into.data.pNext; \ + default_fex_custom_repack_reverse(*reinterpret_cast*>(&into), \ + &reinterpret_cast(from.data)); \ + into = to_guest(from); \ + into.data.pNext = prev_next; \ + return true; \ + } + +// Intentionally left empty. This macro doesn't automate anything, but it +// helps ensure we don't forget any Vulkan types in the list. The actual +// repacking functions are defined manually later +#define VULKAN_NONDEFAULT_CUSTOM_REPACK(name) + +VULKAN_DEFAULT_CUSTOM_REPACK(VkApplicationInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkAttachmentDescription2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkAttachmentReference2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkBufferMemoryBarrier2) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkDependencyInfo) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkDescriptorUpdateTemplateCreateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkDeviceQueueCreateInfo) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkGraphicsPipelineCreateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkImageFormatListCreateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkImageMemoryBarrier2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkImageMemoryRequirementsInfo2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkImageViewCreateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkMemoryAllocateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkMemoryAllocateFlagsInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkMemoryBarrier2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkMemoryDedicatedAllocateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkMemoryDedicatedRequirements) +VULKAN_DEFAULT_CUSTOM_REPACK(VkMemoryRequirements2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkPipelineRenderingCreateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkRenderPassAttachmentBeginInfo) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkRenderPassBeginInfo) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkRenderPassCreateInfo) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkRenderPassCreateInfo2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkSemaphoreCreateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkSemaphoreTypeCreateInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkSemaphoreWaitInfo) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkSubmitInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkSubpassBeginInfo) +VULKAN_DEFAULT_CUSTOM_REPACK(VkSubpassDependency2) +VULKAN_NONDEFAULT_CUSTOM_REPACK(VkSubpassDescription2) +VULKAN_DEFAULT_CUSTOM_REPACK(VkSwapchainCreateInfoKHR) +VULKAN_DEFAULT_CUSTOM_REPACK(VkTimelineSemaphoreSubmitInfo) + + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + + auto HostApplicationInfo = new host_layout {*from.data.pApplicationInfo.get_pointer()}; + fex_apply_custom_repacking_entry(*HostApplicationInfo, *from.data.pApplicationInfo.get_pointer()); + + into.data.pApplicationInfo = &HostApplicationInfo->data; + + auto extension_count = from.data.enabledExtensionCount.data; + into.data.ppEnabledExtensionNames = RepackStructArray(extension_count, from.data.ppEnabledExtensionNames).data(); + + auto layer_count = from.data.enabledLayerCount.data; + into.data.ppEnabledLayerNames = RepackStructArray(layer_count, from.data.ppEnabledLayerNames).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete from.data.pApplicationInfo; + delete[] from.data.ppEnabledExtensionNames; + delete[] from.data.ppEnabledLayerNames; + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + + auto HostQueueCreateInfo = new host_layout {*from.data.pQueueCreateInfos.get_pointer()}; + fex_apply_custom_repacking_entry(*HostQueueCreateInfo, *from.data.pQueueCreateInfos.get_pointer()); + into.data.pQueueCreateInfos = &HostQueueCreateInfo->data; + + auto layer_count = from.data.enabledExtensionCount.data; + fprintf(stderr, " Repacking %d ppEnabledLayerNames\n", layer_count); + into.data.ppEnabledLayerNames = RepackStructArray(layer_count, from.data.ppEnabledLayerNames).data(); + + auto extension_count = from.data.enabledExtensionCount.data; + fprintf(stderr, " Repacking %d ppEnabledExtensionNames\n", extension_count); + into.data.ppEnabledExtensionNames = RepackStructArray(extension_count, from.data.ppEnabledExtensionNames).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete from.data.pQueueCreateInfos; + delete[] from.data.ppEnabledExtensionNames; + delete[] from.data.ppEnabledLayerNames; + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pBindings = RepackStructArray(from.data.bindingCount.data, from.data.pBindings).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pBindings; + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pSubpasses = RepackStructArray(from.data.subpassCount.data, from.data.pSubpasses).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pSubpasses; + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pAttachments = RepackStructArray(from.data.attachmentCount.data, from.data.pAttachments).data(); + into.data.pSubpasses = RepackStructArray(from.data.subpassCount.data, from.data.pSubpasses).data(); + into.data.pDependencies = RepackStructArray(from.data.dependencyCount.data, from.data.pDependencies).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pAttachments; + // TODO: Run custom exit-repacking + delete[] from.data.pSubpasses; + // TODO: Run custom exit-repacking + delete[] from.data.pDependencies; + // TODO: Run custom exit-repacking + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pInputAttachments = RepackStructArray(from.data.inputAttachmentCount.data, from.data.pInputAttachments).data(); + into.data.pColorAttachments = RepackStructArray(from.data.colorAttachmentCount.data, from.data.pColorAttachments).data(); + into.data.pResolveAttachments = RepackStructArray(from.data.colorAttachmentCount.data, from.data.pResolveAttachments).data(); + + if (from.data.pDepthStencilAttachment.data == 0) { + into.data.pDepthStencilAttachment = nullptr; + } else { + into.data.pDepthStencilAttachment = new VkAttachmentReference2; + auto in_data = host_layout {*from.data.pDepthStencilAttachment.get_pointer()}; + fex_apply_custom_repacking_entry(in_data, *from.data.pDepthStencilAttachment.get_pointer()); + memcpy((void*)into.data.pDepthStencilAttachment, &in_data.data, sizeof(VkAttachmentReference2)); + } +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pInputAttachments; + // TODO: Run custom exit-repacking + delete[] from.data.pColorAttachments; + // TODO: Run custom exit-repacking + delete[] from.data.pResolveAttachments; + // TODO: Run custom exit-repacking + delete /*[]*/ from.data.pDepthStencilAttachment; + // TODO: Run custom exit-repacking + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + + into.data.pColorAttachments = RepackStructArray(from.data.colorAttachmentCount.data, from.data.pColorAttachments).data(); + + if (from.data.pDepthAttachment.get_pointer() == nullptr) { + into.data.pDepthAttachment = nullptr; + } else { + into.data.pDepthAttachment = new VkRenderingAttachmentInfo; + auto in_data = host_layout {*from.data.pDepthAttachment.get_pointer()}; + fex_apply_custom_repacking_entry(in_data, *from.data.pDepthAttachment.get_pointer()); + memcpy((void*)into.data.pDepthAttachment, &in_data.data, sizeof(VkRenderingAttachmentInfo)); + } + + if (from.data.pStencilAttachment.get_pointer() == nullptr) { + into.data.pStencilAttachment = nullptr; + } else { + into.data.pStencilAttachment = new VkRenderingAttachmentInfo; + auto in_data = host_layout {*from.data.pStencilAttachment.get_pointer()}; + fex_apply_custom_repacking_entry(in_data, *from.data.pStencilAttachment.get_pointer()); + memcpy((void*)into.data.pStencilAttachment, &in_data.data, sizeof(VkRenderingAttachmentInfo)); + } +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pColorAttachments; + // TODO: Run custom exit-repacking + delete from.data.pDepthAttachment; + // TODO: Run custom exit-repacking + delete from.data.pStencilAttachment; + // TODO: Run custom exit-repacking + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pMemoryBarriers = RepackStructArray(from.data.memoryBarrierCount.data, from.data.pMemoryBarriers).data(); + into.data.pImageMemoryBarriers = RepackStructArray(from.data.imageMemoryBarrierCount.data, from.data.pImageMemoryBarriers).data(); + into.data.pBufferMemoryBarriers = RepackStructArray(from.data.bufferMemoryBarrierCount.data, from.data.pBufferMemoryBarriers).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pMemoryBarriers; + // TODO: Run custom exit-repacking + delete[] from.data.pBufferMemoryBarriers; + // TODO: Run custom exit-repacking + delete[] from.data.pImageMemoryBarriers; + // TODO: Run custom exit-repacking + return false; +} + +void fex_custom_repack_entry(host_layout& into, + const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pDescriptorUpdateEntries = RepackStructArray(from.data.descriptorUpdateEntryCount.data, from.data.pDescriptorUpdateEntries).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pDescriptorUpdateEntries; + // TODO: Run custom exit-repacking + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + if (from.data.pSpecializationInfo.get_pointer()) { + fprintf(stderr, "ERROR: Cannot repack non-null VkPipelineShaderStageCreateInfo::pSpecializationInfo yet"); + std::abort(); + } +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + // TODO + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pStages = RepackStructArray(from.data.stageCount.data, from.data.pStages).data(); + + if (!from.data.pVertexInputState.get_pointer()) { + into.data.pVertexInputState = nullptr; + } else { + into.data.pVertexInputState = &(new host_layout {*from.data.pVertexInputState.get_pointer()})->data; + } + + if (!from.data.pInputAssemblyState.get_pointer()) { + into.data.pInputAssemblyState = nullptr; + } else { + into.data.pInputAssemblyState = + &(new host_layout {*from.data.pInputAssemblyState.get_pointer()})->data; + } + + if (!from.data.pTessellationState.get_pointer()) { + into.data.pTessellationState = nullptr; + } else { + into.data.pTessellationState = &(new host_layout {*from.data.pTessellationState.get_pointer()})->data; + } + + if (!from.data.pViewportState.get_pointer()) { + into.data.pViewportState = nullptr; + } else { + into.data.pViewportState = &(new host_layout {*from.data.pViewportState.get_pointer()})->data; + } + + if (!from.data.pRasterizationState.get_pointer()) { + into.data.pRasterizationState = nullptr; + } else { + into.data.pRasterizationState = + &(new host_layout {*from.data.pRasterizationState.get_pointer()})->data; + } + + if (!from.data.pMultisampleState.get_pointer()) { + into.data.pMultisampleState = nullptr; + } else { + into.data.pMultisampleState = &(new host_layout {*from.data.pMultisampleState.get_pointer()})->data; + } + + if (!from.data.pDepthStencilState.get_pointer()) { + into.data.pDepthStencilState = nullptr; + } else { + into.data.pDepthStencilState = &(new host_layout {*from.data.pDepthStencilState.get_pointer()})->data; + } + + if (!from.data.pColorBlendState.get_pointer()) { + into.data.pColorBlendState = nullptr; + } else { + into.data.pColorBlendState = &(new host_layout {*from.data.pColorBlendState.get_pointer()})->data; + } + + if (!from.data.pDynamicState.get_pointer()) { + into.data.pDynamicState = nullptr; + } else { + into.data.pDynamicState = &(new host_layout {*from.data.pDynamicState.get_pointer()})->data; + } +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pStages; + delete from.data.pVertexInputState; + delete from.data.pInputAssemblyState; + delete from.data.pTessellationState; + delete from.data.pViewportState; + delete from.data.pRasterizationState; + delete from.data.pMultisampleState; + delete from.data.pDepthStencilState; + delete from.data.pColorBlendState; + delete from.data.pDynamicState; + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + into.data.pCommandBuffers = RepackStructArray(from.data.commandBufferCount.data, from.data.pCommandBuffers).data(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete[] from.data.pCommandBuffers; + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + + if (!from.data.pInheritanceInfo.get_pointer() || !from.data.pInheritanceInfo.data) { + into.data.pInheritanceInfo = nullptr; + return; + } + into.data.pInheritanceInfo = new VkCommandBufferInheritanceInfo; + auto src = host_layout {*from.data.pInheritanceInfo.get_pointer()}.data; + static_assert(sizeof(src) == sizeof(*into.data.pInheritanceInfo)); + memcpy((void*)into.data.pInheritanceInfo, &src, sizeof(src)); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + delete from.data.pInheritanceInfo; + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + + // Same underlying layout, so there's nothing to do + into.data.pInitialData = from.data.pInitialData.get_pointer(); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + // Nothing to do + return false; +} + +void fex_custom_repack_entry(host_layout& into, const guest_layout& from) { + default_fex_custom_repack_entry(into, from); + + // Same underlying layout, so there's nothing to do + into.data.pClearValues = reinterpret_cast(from.data.pClearValues.get_pointer()); +} + +bool fex_custom_repack_exit(guest_layout& into, const host_layout& from) { + // Nothing to do + return false; +} +#endif + EXPORTS(libvulkan) diff --git a/ThunkLibs/libvulkan/libvulkan_interface.cpp b/ThunkLibs/libvulkan/libvulkan_interface.cpp index 41e320ced..c5f21875f 100644 --- a/ThunkLibs/libvulkan/libvulkan_interface.cpp +++ b/ThunkLibs/libvulkan/libvulkan_interface.cpp @@ -95,7 +95,171 @@ struct fex_gen_type : fexgen::emit_layout_wr template<> struct fex_gen_type : fexgen::emit_layout_wrappers {}; -#ifndef IS_32BIT_THUNK +#ifdef IS_32BIT_THUNK +// Register structs with an extension point (pNext). Any other members that need customization are listed below. +template<> +struct fex_gen_config<&VkApplicationInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkAttachmentDescription2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkAttachmentReference2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_type : fexgen::emit_layout_wrappers {}; +template<> +struct fex_gen_config<&VkBufferMemoryBarrier2::pNext> : fexgen::custom_repack {}; +// template<> struct fex_gen_config<&VkCommandBufferBeginInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDependencyInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDescriptorUpdateTemplateCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDeviceCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDeviceQueueCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkImageFormatListCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkImageMemoryBarrier2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkImageMemoryRequirementsInfo2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkImageViewCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkInstanceCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkMemoryAllocateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkMemoryAllocateFlagsInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkMemoryBarrier2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkMemoryDedicatedAllocateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkMemoryDedicatedRequirements::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkMemoryRequirements2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkPipelineRenderingCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderPassAttachmentBeginInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderPassBeginInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderPassCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderPassCreateInfo2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSemaphoreCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSemaphoreTypeCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSemaphoreWaitInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSubmitInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSubpassBeginInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSubpassDependency2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSubpassDescription2::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSwapchainCreateInfoKHR::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkTimelineSemaphoreSubmitInfo::pNext> : fexgen::custom_repack {}; + + +template<> +struct fex_gen_config<&VkDeviceCreateInfo::pQueueCreateInfos> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDeviceCreateInfo::ppEnabledLayerNames> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDeviceCreateInfo::ppEnabledExtensionNames> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkDescriptorSetLayoutCreateInfo::pNext> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDescriptorSetLayoutCreateInfo::pBindings> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkInstanceCreateInfo::pApplicationInfo> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkInstanceCreateInfo::ppEnabledLayerNames> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkInstanceCreateInfo::ppEnabledExtensionNames> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkRenderPassCreateInfo::pSubpasses> : fexgen::custom_repack {}; +// NOTE: pDependencies and pAttachments point to ABI-compatible data + +template<> +struct fex_gen_config<&VkRenderPassCreateInfo2::pAttachments> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderPassCreateInfo2::pSubpasses> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderPassCreateInfo2::pDependencies> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkPipelineShaderStageCreateInfo::pSpecializationInfo> : fexgen::custom_repack {}; +// template<> struct fex_gen_config<&VkSpecializationInfo::pMapEntries> : fexgen::custom_repack {}; + + +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pStages> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pVertexInputState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pInputAssemblyState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pTessellationState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pViewportState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pRasterizationState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pMultisampleState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pDepthStencilState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pColorBlendState> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkGraphicsPipelineCreateInfo::pDynamicState> : fexgen::custom_repack {}; + +// Command buffers are dispatchable handles, so on 32-bit they need to be repacked +template<> +struct fex_gen_config<&VkSubmitInfo::pCommandBuffers> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkRenderingInfo::pColorAttachments> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderingInfo::pDepthAttachment> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkRenderingInfo::pStencilAttachment> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkSubpassDescription2::pInputAttachments> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSubpassDescription2::pColorAttachments> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSubpassDescription2::pResolveAttachments> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkSubpassDescription2::pDepthStencilAttachment> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkDependencyInfo::pMemoryBarriers> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDependencyInfo::pBufferMemoryBarriers> : fexgen::custom_repack {}; +template<> +struct fex_gen_config<&VkDependencyInfo::pImageMemoryBarriers> : fexgen::custom_repack {}; + +template<> +struct fex_gen_config<&VkDescriptorUpdateTemplateCreateInfo::pDescriptorUpdateEntries> : fexgen::custom_repack {}; + +// These types have incompatible data layout but we use their layout wrappers elsewhere +template<> +struct fex_gen_type : fexgen::emit_layout_wrappers {}; +#else // The pNext member of this is a pointer to another VkBaseOutStructure, so data layout compatibility can't be inferred automatically template<> struct fex_gen_type : fexgen::assume_compatible_data_layout {}; @@ -127,14 +291,36 @@ struct fex_gen_param {}; template struct fex_gen_config : fexgen::generate_guest_symtable, fexgen::indirect_guest_calls {}; +#ifdef IS_32BIT_THUNK +template<> +struct fex_gen_config<&VkCommandBufferBeginInfo::pInheritanceInfo> : fexgen::custom_repack {}; + +// TODO: Should have per-member compatibility annotation +template<> +struct fex_gen_config<&VkPipelineCacheCreateInfo::pInitialData> : fexgen::custom_repack {}; + +// TODO: Should have per-member compatibility annotation +template<> +struct fex_gen_config<&VkRenderPassBeginInfo::pClearValues> : fexgen::custom_repack {}; +#endif + template<> struct fex_gen_config : fexgen::custom_host_impl {}; template<> struct fex_gen_param : fexgen::ptr_passthrough {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif + + template<> struct fex_gen_config {}; template<> @@ -162,10 +348,25 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +// Needs array repacking for multiple submit infos +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif template<> struct fex_gen_config {}; template<> @@ -174,16 +375,25 @@ template<> struct fex_gen_config : fexgen::custom_host_impl {}; template<> struct fex_gen_config : fexgen::custom_host_impl {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -192,26 +402,31 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -230,6 +445,7 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_param : fexgen::assume_compatible_data_layout {}; +#endif template<> struct fex_gen_config {}; template<> @@ -256,14 +472,28 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif +template<> +struct fex_gen_param : fexgen::assume_compatible_data_layout {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#endif +// TODO: Should be custom_host_impl since there may be more than one VkGraphicsPipelineCreateInfo and more than one output pipeline template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -288,8 +518,17 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif template<> struct fex_gen_config {}; template<> @@ -306,10 +545,25 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif + +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif template<> struct fex_gen_config {}; template<> @@ -344,6 +598,7 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -360,20 +615,26 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> +struct fex_gen_param : fexgen::assume_compatible_data_layout {}; +template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -382,8 +643,10 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -397,15 +660,23 @@ struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> +struct fex_gen_param : fexgen::assume_compatible_data_layout {}; +#endif +template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -418,12 +689,15 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -432,6 +706,7 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -446,6 +721,7 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -454,20 +730,25 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_param : fexgen::assume_compatible_data_layout {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -478,8 +759,10 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -504,8 +787,10 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -522,10 +807,12 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -562,6 +849,7 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -609,7 +897,7 @@ struct fex_gen_config {}; template<> struct fex_gen_config {}; template<> -struct fex_gen_config {}; +struct fex_gen_config {}; // TODO: Need to figure out how *not* to repack the last parameter on input... template<> struct fex_gen_config {}; template<> @@ -622,6 +910,7 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -714,20 +1003,24 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> struct fex_gen_param : fexgen::assume_compatible_data_layout {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> struct fex_gen_param : fexgen::assume_compatible_data_layout {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -900,12 +1193,14 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config : fexgen::custom_host_impl {}; template<> struct fex_gen_param : fexgen::ptr_passthrough {}; template<> struct fex_gen_config : fexgen::custom_host_impl {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -1002,12 +1297,14 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config : fexgen::custom_host_impl {}; template<> struct fex_gen_param : fexgen::ptr_passthrough {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -1070,10 +1367,12 @@ template<> struct fex_gen_param : fexgen::assume_compatible_data_layout {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -1236,8 +1535,11 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK +// VkRemoteAddressNV* expands to void**, so it needs custom repacking on on 32-bit template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -1250,8 +1552,10 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -1514,8 +1818,10 @@ template<> struct fex_gen_param : fexgen::ptr_passthrough {}; // vulkan_wayland.h +#endif template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; @@ -1534,5 +1840,5 @@ template<> struct fex_gen_config : fexgen::custom_host_impl {}; template<> struct fex_gen_param : fexgen::ptr_passthrough {}; - +#endif } // namespace internal