From 1e9d774483162288fabd9ed97df29ddf04815eab Mon Sep 17 00:00:00 2001 From: Unknown <0.tamas.marton@gmail.com> Date: Tue, 1 Oct 2019 00:39:24 +0100 Subject: [PATCH] finally the trampoline walking works can successfully call my custom extension TODO: need to make the assembly loader work too --- driver/declarations.h | 35 +++++++++++++++++++++++++++++++++++ driver/instance.c | 7 +++++++ driver/vkCaps.h | 1 + driver/vkExt.h | 27 ++++++++++++++++++++++++--- driver/vkExtFunctions.c | 35 +++++++++++++++++++---------------- driver/wsi.c | 29 +++++++++++++++++++++++------ test/blending/blending.cpp | 18 ++++++++++++------ 7 files changed, 121 insertions(+), 31 deletions(-) diff --git a/driver/declarations.h b/driver/declarations.h index 6d0f81a..de7e225 100644 --- a/driver/declarations.h +++ b/driver/declarations.h @@ -4,6 +4,7 @@ extern "C" { #endif +#define VK_NO_PROTOTYPES #include VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateInstance( @@ -948,6 +949,40 @@ VKAPI_ATTR void VKAPI_CALL rpi_vkGetDescriptorSetLayoutSupport( const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); +VKAPI_ATTR void VKAPI_CALL rpi_vkDestroySurfaceKHR( + VkInstance instance, + VkSurfaceKHR surface, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateSwapchainKHR( + VkDevice device, + const VkSwapchainCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchain); + +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfaceSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + VkSurfaceKHR surface, + VkBool32* pSupported); + +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfaceFormatsKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pSurfaceFormatCount, + VkSurfaceFormatKHR* pSurfaceFormats); + +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfacePresentModesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pPresentModeCount, + VkPresentModeKHR* pPresentModes); + #ifdef __cplusplus } #endif diff --git a/driver/instance.c b/driver/instance.c index 59da11e..c06229b 100644 --- a/driver/instance.c +++ b/driver/instance.c @@ -380,6 +380,13 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL rpi_vkGetInstanceProcAddr( RETFUNC(vkGetDescriptorSetLayoutSupport); RETFUNC(vkBindBufferMemory2); + RETFUNC(vkDestroySurfaceKHR); + RETFUNC(vkCreateSwapchainKHR); + RETFUNC(vkGetPhysicalDeviceSurfaceSupportKHR); + RETFUNC(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + RETFUNC(vkGetPhysicalDeviceSurfaceFormatsKHR); + RETFUNC(vkGetPhysicalDeviceSurfacePresentModesKHR); + return 0; } diff --git a/driver/vkCaps.h b/driver/vkCaps.h index ac552e8..ee34aca 100644 --- a/driver/vkCaps.h +++ b/driver/vkCaps.h @@ -1,5 +1,6 @@ #pragma once +#define VK_NO_PROTOTYPES #include //https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#features-limits diff --git a/driver/vkExt.h b/driver/vkExt.h index 84432b7..4529290 100644 --- a/driver/vkExt.h +++ b/driver/vkExt.h @@ -1,5 +1,6 @@ #pragma once +#define VK_NO_PROTOTYPES #include #ifdef __cplusplus @@ -8,15 +9,35 @@ extern "C" { typedef VkResult (*PFN_vkCreateRpiSurfaceEXT)( VkPhysicalDevice physicalDevice); -typedef VkResult (*PFN__vkCreateShaderModuleFromRpiAssemblyEXT)( +typedef VkResult (*PFN_vkCreateShaderModuleFromRpiAssemblyEXT)( VkPhysicalDevice physicalDevice); +// Sooo we're not really getting the REAL VkPhysicalDevice from the Loader +// But rather a Trampoline object that points to a Terminator that finally points to +// The real object +// Therefore if we would like to pass on information in our VkPhysicalDevice object +// We need to walk this chain... typedef struct VkRpiPhysicalDevice { - void* dummy; - void* customData; + uintptr_t loaderData; + uintptr_t customData; } VkRpiPhysicalDevice; +typedef struct LoaderTerminator +{ + uintptr_t a; + uintptr_t b; + uint8_t c; + VkRpiPhysicalDevice* physicalDevice; +} LoaderTerminator; + +typedef struct LoaderTrampoline +{ + uintptr_t a; + uintptr_t b; + LoaderTerminator* loaderTerminator; +} LoaderTrampoline; + //we need something like the other platforms to create surfaces on the RPI //so I created this little "extension" //full spec in this file ;) diff --git a/driver/vkExtFunctions.c b/driver/vkExtFunctions.c index 8b149fb..a5d4f24 100644 --- a/driver/vkExtFunctions.c +++ b/driver/vkExtFunctions.c @@ -9,6 +9,25 @@ extern "C" { #endif +/* + * Implementation of our RPI specific "extension" + */ +VkResult rpi_vkCreateRpiSurfaceEXT( + VkPhysicalDevice physicalDevice) +{ + assert(physicalDevice); + + //TODO use allocator! + + _physicalDevice* ptr = physicalDevice; + VkSurfaceKHR* surfPtr = ptr->customData; + VkSurfaceKHR surfRes = (VkSurfaceKHR)modeset_create(controlFd); + + *surfPtr = surfRes; + + return VK_SUCCESS; +} + //TODO collect shader performance data //eg number of texture samples etc. //TODO check if shader has flow control and make sure instance also has flow control @@ -119,22 +138,6 @@ VkResult rpi_vkCreateShaderModuleFromRpiAssemblyEXT(VkPhysicalDevice return VK_SUCCESS; } -/* - * Implementation of our RPI specific "extension" - */ -VkResult rpi_vkCreateRpiSurfaceEXT( - VkPhysicalDevice physicalDevice) -{ - assert(physicalDevice); - - //TODO use allocator! - - _physicalDevice* ptr = physicalDevice; - *(VkSurfaceKHR*)ptr->customData = (VkSurfaceKHR)modeset_create(controlFd); - - return VK_SUCCESS; -} - #ifdef __cplusplus } #endif diff --git a/driver/wsi.c b/driver/wsi.c index 552c7a7..5fdaadf 100644 --- a/driver/wsi.c +++ b/driver/wsi.c @@ -5,13 +5,26 @@ #include "declarations.h" +#ifdef __cplusplus +extern "C" { +#endif + +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateDisplayPlaneSurfaceKHR( + VkInstance instance, + const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface) +{ + fprintf(stderr, "vkCreateDisplayPlaneSurfaceKHR\n"); +} + /* * https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkDestroySurfaceKHR * Destroying a VkSurfaceKHR merely severs the connection between Vulkan and the native surface, * and does not imply destroying the native surface, closing a window, or similar behavior * (but we'll do so anyways...) */ -VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( +VKAPI_ATTR void VKAPI_CALL rpi_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator) @@ -36,7 +49,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( * * capabilities the specified device supports for a swapchain created for the surface */ -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) @@ -71,7 +84,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( * at most pSurfaceFormatCount structures will be written. If pSurfaceFormatCount is smaller than the number of format pairs supported for the given surface, * VK_INCOMPLETE will be returned instead of VK_SUCCESS to indicate that not all the available values were returned. */ -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfaceFormatsKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, @@ -116,7 +129,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( * If pPresentModeCount is smaller than the number of presentation modes supported for the given surface, VK_INCOMPLETE will be returned instead of * VK_SUCCESS to indicate that not all the available values were returned. */ -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfacePresentModesKHR( VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, @@ -156,7 +169,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( /* * https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCreateSwapchainKHR */ -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateSwapchainKHR( VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -404,7 +417,7 @@ VKAPI_ATTR void VKAPI_CALL rpi_vkDestroySwapchainKHR( * https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR * does this queue family support presentation to this surface? */ -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( +VKAPI_ATTR VkResult VKAPI_CALL rpi_vkGetPhysicalDeviceSurfaceSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, @@ -422,3 +435,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( *pSupported = VK_TRUE; return VK_SUCCESS; } + +#ifdef __cplusplus +} +#endif diff --git a/test/blending/blending.cpp b/test/blending/blending.cpp index 45d7e1f..7f770bf 100644 --- a/test/blending/blending.cpp +++ b/test/blending/blending.cpp @@ -231,14 +231,17 @@ void createInstance() { debugCallbackInfo.flags = 0xffffffff; debugCallbackInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugCallback; + const char* enabledExtensions[] = { + "VK_KHR_surface", + "VK_KHR_display" + }; + VkInstanceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pNext = &debugCallbackInfo; createInfo.pApplicationInfo = &appInfo; - //createInfo.enabledExtensionCount = glfwExtensionCount; - createInfo.enabledExtensionCount = 0; - //createInfo.ppEnabledExtensionNames = glfwExtensions; - createInfo.ppEnabledExtensionNames = 0; + createInfo.enabledExtensionCount = sizeof(enabledExtensions) / sizeof(const char*); + createInfo.ppEnabledExtensionNames = enabledExtensions; createInfo.enabledLayerCount = 0; createInfo.ppEnabledLayerNames = 0; @@ -257,8 +260,11 @@ void createWindowSurface() { PFN_vkCreateRpiSurfaceEXT vkCreateRpiSurfaceEXT = 0; vkCreateRpiSurfaceEXT = (PFN_vkCreateRpiSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateRpiSurfaceEXT"); - VkRpiPhysicalDevice* ptr = (VkRpiPhysicalDevice*)physicalDevice; - ptr->customData = &windowSurface; + windowSurface = 0; + + LoaderTrampoline* trampoline = (LoaderTrampoline*)physicalDevice; + VkRpiPhysicalDevice* realPhysicalDevice = trampoline->loaderTerminator->physicalDevice; + realPhysicalDevice->customData = (uintptr_t)&windowSurface; if (vkCreateRpiSurfaceEXT(physicalDevice) != VK_SUCCESS) { std::cerr << "failed to create window surface!" << std::endl;