diff --git a/driver/declarations.h b/driver/declarations.h index b83b5c0..46bd098 100644 --- a/driver/declarations.h +++ b/driver/declarations.h @@ -1,5 +1,9 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + #include VKAPI_ATTR VkResult VKAPI_CALL rpi_vkCreateInstance( @@ -948,3 +952,7 @@ VKAPI_ATTR void VKAPI_CALL rpi_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); + +#ifdef __cplusplus +} +#endif diff --git a/driver/instance.c b/driver/instance.c index d3d5442..f6f4807 100644 --- a/driver/instance.c +++ b/driver/instance.c @@ -3,9 +3,9 @@ #include #include "declarations.h" -#include "vkExt.h" +#include "vkExtFunctions.h" -#define RETFUNC(f) if(!strcmp(pName, #f)) return rpi_##f +#define RETFUNC(f) if(!strcmp(pName, #f)) return &rpi_##f static uint32_t loaderVersion = -1; @@ -14,20 +14,23 @@ VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t assert(pSupportedVersion); loaderVersion = *pSupportedVersion; - *pSupportedVersion = 2; //we support v2 + *pSupportedVersion = 4; //we support v4 + + return VK_SUCCESS; } VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName) { - fprintf(stderr, "-----------------vk_icdGetInstanceProcAddr: %s\n", pName); - if(loaderVersion == -1) { //dealing with legacy ICD loader, as vk_icdNegotiateLoaderICDInterfaceVersion has not been called loaderVersion = 1; } - return rpi_vkGetInstanceProcAddr(instance, pName); + void* ptr = rpi_vkGetInstanceProcAddr(instance, pName); + + fprintf(stderr, "-----------------rpi_vkGetInstanceProcAddr: %s, %p\n", pName, ptr); + return ptr; } VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, @@ -35,7 +38,7 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInsta { fprintf(stderr, "-----------------vk_icdGetPhysicalDeviceProcAddr: %s\n", pName); - + RETFUNC(vkGetRpiExtensionPointerEXT); return 0; } @@ -195,8 +198,6 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL rpi_vkGetInstanceProcAddr( VkInstance instance, const char* pName) { - fprintf(stderr, "-----------------rpi_vkGetInstanceProcAddr: %s\n", pName); - //TODO take instance into consideration //eg only return extension functions that are enabled? @@ -376,9 +377,6 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL rpi_vkGetInstanceProcAddr( RETFUNC(vkGetDescriptorSetLayoutSupport); RETFUNC(vkBindBufferMemory2); - RETFUNC(vkCreateRpiSurfaceEXT); - RETFUNC(vkCreateShaderModuleFromRpiAssemblyEXT); - return 0; } diff --git a/driver/shader.c b/driver/shader.c index fbca0cf..8cf6994 100644 --- a/driver/shader.c +++ b/driver/shader.c @@ -4,12 +4,17 @@ #include "QPUassembler/qpu_assembler.h" +#include "vkExt.h" + //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 //TODO make sure instance has threaded fs if shader contains thread switch -VkResult rpi_vkCreateShaderModuleFromRpiAssemblyEXT(VkDevice device, VkRpiShaderModuleAssemblyCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule) +VkResult rpi_vkCreateShaderModuleFromRpiAssemblyEXT(VkDevice device, + VkRpiShaderModuleAssemblyCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkShaderModule* pShaderModule) { assert(device); assert(pCreateInfo); diff --git a/driver/vkExt.h b/driver/vkExt.h index 92204f6..5311c8a 100644 --- a/driver/vkExt.h +++ b/driver/vkExt.h @@ -1,9 +1,5 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - //we need something like the other platforms to create surfaces on the RPI //so I created this little "extension" //full spec in this file ;) @@ -71,28 +67,3 @@ typedef struct VkRpiShaderModuleAssemblyCreateInfoEXT { VkRpiAssemblyMappingEXT* mappings; uint32_t numMappings; } VkRpiShaderModuleAssemblyCreateInfoEXT; - -//TODO could use this extension https://vulkan.lunarg.com/doc/view/1.0.30.0/windows/vkspec.chunked/ch29s03.html - -//extension name something like: VK_KHR_rpi_surface -//extension that allows developers to create a surface to render to on Raspbian Stretch Lite -VkResult rpi_vkCreateRpiSurfaceEXT( - VkInstance instance, - const VkRpiSurfaceCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -//extension that allows developers to submit QPU assembly directly and thus hand optimise code -VkResult rpi_vkCreateShaderModuleFromRpiAssemblyEXT( - VkDevice device, - VkRpiShaderModuleAssemblyCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkShaderModule* pShaderModule - ); - -//TODO performance counters / perfmon - - -#ifdef __cplusplus -} -#endif diff --git a/driver/vkExtFunctions.h b/driver/vkExtFunctions.h new file mode 100644 index 0000000..0ec20e8 --- /dev/null +++ b/driver/vkExtFunctions.h @@ -0,0 +1,48 @@ +#pragma once + +#include "vkExt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//extension name something like: VK_KHR_rpi_surface +//extension that allows developers to create a surface to render to on Raspbian Stretch Lite +extern VkResult rpi_vkCreateRpiSurfaceEXT( + VkInstance instance, + const VkRpiSurfaceCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +//extension that allows developers to submit QPU assembly directly and thus hand optimise code +extern VkResult rpi_vkCreateShaderModuleFromRpiAssemblyEXT( + VkDevice device, + VkRpiShaderModuleAssemblyCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkShaderModule* pShaderModule + ); + +extern void* _getFuncPtr(const char* name); + +static VkResult rpi_vkGetRpiExtensionPointerEXT( + VkPhysicalDevice physicalDevice + ) +{ + //TODO how do we handle our "custom" extensions towards the loader???? + + uint32_t ret = 0;//(uint32_t)_getFuncPtr((const char*)physicalDevice); + + if(ret) + { + return (VkResult)ret; + } + + return VK_SUCCESS; +} + +//TODO performance counters / perfmon + + +#ifdef __cplusplus +} +#endif diff --git a/driver/wsi.c b/driver/wsi.c index da843ee..622de16 100644 --- a/driver/wsi.c +++ b/driver/wsi.c @@ -5,6 +5,29 @@ #include "declarations.h" +#include "vkExtFunctions.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void* _getFuncPtr(const char* name) +{ + if(!strcmp(name, "vkCreateRpiSurfaceEXT")) + return (void*)&rpi_vkCreateRpiSurfaceEXT; + + if(!strcmp(name, "vkCreateShaderModuleFromRpiAssemblyEXT")) + return (void*)&rpi_vkCreateShaderModuleFromRpiAssemblyEXT; + + return 0; +} + +#ifdef __cplusplus +} +#endif + + /* * Implementation of our RPI specific "extension" */ diff --git a/test/blending/blending.cpp b/test/blending/blending.cpp index 666563e..fe27168 100644 --- a/test/blending/blending.cpp +++ b/test/blending/blending.cpp @@ -132,8 +132,8 @@ void run() { void setupVulkan() { createInstance(); - createWindowSurface(); findPhysicalDevice(); + createWindowSurface(); checkSwapChainSupport(); findQueueFamilies(); createLogicalDevice(); @@ -253,17 +253,28 @@ void createInstance() { } } +extern "C" { +typedef VkResult (*PFN_vkCreateRpiSurfaceEXT)( + VkPhysicalDevice physicalDevice, + const VkRpiSurfaceCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +typedef VkResult (*PFN_vkGetRpiExtensionPointerEXT)( + VkPhysicalDevice physicalDevice + ); +} + +PFN_vkGetRpiExtensionPointerEXT vkGetRpiExtensionPointerEXT = 0; + void createWindowSurface() { - typedef VkResult (VKAPI_PTR *PFN_vkCreateRpiSurfaceEXT)( - VkInstance instance, - const VkRpiSurfaceCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); + vkGetRpiExtensionPointerEXT = (PFN_vkGetRpiExtensionPointerEXT)vkGetInstanceProcAddr(instance, "vkGetRpiExtensionPointerEXT"); + fprintf(stderr, "%p\n", vkGetRpiExtensionPointerEXT); - PFN_vkCreateRpiSurfaceEXT vkCreateRpiSurfaceEXT = (PFN_vkCreateRpiSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateRpiSurfaceEXT"); + PFN_vkCreateRpiSurfaceEXT vkCreateRpiSurfaceEXT = 0; + vkCreateRpiSurfaceEXT = (PFN_vkCreateRpiSurfaceEXT)vkGetRpiExtensionPointerEXT((VkPhysicalDevice)"vkCreateRpiSurfaceEXT"); + fprintf(stderr, "%p\n", vkCreateRpiSurfaceEXT); - - if (vkCreateRpiSurfaceEXT(instance, 0, 0, &windowSurface) != VK_SUCCESS) { + if (vkCreateRpiSurfaceEXT(physicalDevice, 0, 0, &windowSurface) != VK_SUCCESS) { std::cerr << "failed to create window surface!" << std::endl; assert(0); }