From 8ded8d465d2441d35d6f509bcfdd546c681d9ec9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Tue, 30 Nov 2021 16:46:05 +0100 Subject: [PATCH] vkvg_device_create->own vk ctx, full vk context creation; vkvg_device_create_from_vk.. to bind existing vk ctx --- include/vkvg.h | 30 ++++++++++++---- src/vkvg_device.c | 74 ++++++++++++++++++++++++++++++++++++-- src/vkvg_device_internal.c | 9 +++++ src/vkvg_device_internal.h | 3 ++ tests/common/test.c | 6 ++-- tests/offscreen.c | 20 +++++++++++ vkh | 2 +- 7 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 tests/offscreen.c diff --git a/include/vkvg.h b/include/vkvg.h index 99a6a1b..6d30680 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -480,17 +480,17 @@ vkvg_status_t vkvg_matrix_invert (vkvg_matrix_t *matrix); /*! * @defgroup device Device - * @brief bind vulkan context and vkvg. + * @brief create or use an existing vulkan context for vkvg. * * #VkvgDevice is the starting point of a vkvg rendering infrastructure. It connects an - * existing vulkan context with vkvg. + * existing vulkan context with vkvg, or may create a new one. * * Most of the vulkan rendering component (pipelines, renderpass, ..) are part of the VkvgDevice, * their are shared among drawing contexts. * * Antialiasing level is configured when creating the device by selecting the sample count. - * #vkvg_device_create will create a not antialiased by selecting VK_SAMPLE_COUNT_1_BIT as sample count. - * To create antialiased rendering device, call #vkvg_device_create_multisample with VkSampleCountFlags + * @ref vkvg_device_create will create a non-antialiased dev by selecting VK_SAMPLE_COUNT_1_BIT as sample count. + * To create antialiased rendering device, call @ref vkvg_device_create_multisample with VkSampleCountFlags * greater than one. * * vkvg use a single frame buffer format for now: VK_FORMAT_B8G8R8A8_UNORM. @@ -502,8 +502,24 @@ vkvg_status_t vkvg_matrix_invert (vkvg_matrix_t *matrix); /** * @brief Create a new vkvg device. * + * Create a new #VkvgDevice owning vulkan instance and device. + * + * On success, create a new vkvg device and set its reference count to 1. + * On error, query the device status by calling @ ref vkvg_device_status(). Error could be + * one of the following: + * - VKVG_STATUS_INVALID_FORMAT: the combination of image format and tiling is not supported + * - VKVG_STATUS_NULL_POINTER: vulkan function pointer fetching failed. + * + * @param samples The sample count that will be setup for the surfaces created by this device. + * @param deferredResolve If true, the final simple sampled image of the surface will only be resolved on demand + */ +vkvg_public +VkvgDevice vkvg_device_create (VkSampleCountFlags samples, bool deferredResolve); +/** + * @brief Create a new vkvg device from an existing vulkan logical device. + * * Create a new #VkvgDevice connected to the vulkan context define by an instance, - * a physical device, a logical device, a graphical queue family index and an index + * a physical device, a logical device, a graphical queue family index and an its index. * * On success, create a new vkvg device and set its reference count to 1. * On error, query the device status by calling #vkvg_device_status(). Error could be @@ -519,7 +535,7 @@ vkvg_status_t vkvg_matrix_invert (vkvg_matrix_t *matrix); * @return The handle of the created vkvg device, or null if an error occured. */ vkvg_public -VkvgDevice vkvg_device_create (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex); +VkvgDevice vkvg_device_create_from_vk (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex); /** * @brief Create a new multisampled vkvg device. * @@ -539,7 +555,7 @@ VkvgDevice vkvg_device_create (VkInstance inst, VkPhysicalDevice phy, VkDevice v * @return The handle of the created vkvg device, or null if an error occured. */ vkvg_public -VkvgDevice vkvg_device_create_multisample (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve); +VkvgDevice vkvg_device_create_from_vk_multisample (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve); /** * @brief Decrement the reference count of the device by 1. Release all it's ressources if count reach 0. * diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 2eb833e..49b893b 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -25,11 +25,73 @@ #include "vkh_phyinfo.h" #include "vk_mem_alloc.h" -VkvgDevice vkvg_device_create(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex) +VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve) { + const char* enabledExts [10]; + uint32_t enabledExtsCount = 0, phyCount = 0; +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + enabledExts[enabledExtsCount++] = "VK_EXT_debug_utils"; +#endif + + VkhApp app = vkh_app_create("vkvg", 0, NULL, enabledExtsCount, enabledExts); + +#if defined(DEBUG) && defined (VKVG_DBG_UTILS) + vkh_app_enable_debug_messenger(app + , VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT + , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + , NULL); +#endif + VkhPhyInfo* phys = vkh_app_get_phyinfos (app, &phyCount, VK_NULL_HANDLE); + if (phyCount == 0) { + vkh_app_destroy (app); + return NULL; + } + + VkhPhyInfo pi = 0; + if (!_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi)) + if (!_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi)) + pi = phys[0]; + + uint32_t qCount = 0; + float qPriorities[] = {0.0}; + VkDeviceQueueCreateInfo pQueueInfos[] = { {0},{0},{0} }; + + if (vkh_phyinfo_create_queues (pi, pi->gQueue, 1, qPriorities, &pQueueInfos[qCount])) + qCount++; + + VkPhysicalDeviceFeatures enabledFeatures = { + //.fillModeNonSolid = true, + }; + + enabledExtsCount=0; + //enabledExts[enabledExtsCount++] = "VK_KHR_swapchain"; + + VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .queueCreateInfoCount = qCount, + .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos, + .enabledExtensionCount = enabledExtsCount, + .ppEnabledExtensionNames = enabledExts, + .pEnabledFeatures = &enabledFeatures}; + + VkhDevice vkhd = vkh_device_create(app, pi, &device_info); + + VkvgDevice vkvgDev = vkvg_device_create_from_vk_multisample ( + vkh_app_get_inst(app), + vkh_device_get_phy(vkhd), + vkh_device_get_vkdev(vkhd), + pi->gQueue, 0, + samples, deferredResolve); + + vkvgDev->vkhDev = vkhd; + + vkh_app_free_phyinfos (phyCount, phys); + + return vkvgDev; +} +VkvgDevice vkvg_device_create_from_vk(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex) { - return vkvg_device_create_multisample (inst,phy,vkdev,qFamIdx,qIndex, VK_SAMPLE_COUNT_1_BIT, false); + return vkvg_device_create_from_vk_multisample (inst,phy,vkdev,qFamIdx,qIndex, VK_SAMPLE_COUNT_1_BIT, false); } -VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve) +VkvgDevice vkvg_device_create_from_vk_multisample(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve) { LOG(VKVG_LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex); @@ -169,6 +231,12 @@ void vkvg_device_destroy (VkvgDevice dev) MUTEX_DESTROY (&dev->gQMutex); + if (dev->vkhDev) { + VkhApp app = vkh_device_get_app (dev->vkhDev); + vkh_device_destroy (dev->vkhDev); + vkh_app_destroy (app); + } + free(dev); } diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 39e2d12..84a64eb 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -48,6 +48,15 @@ PFN_vkCmdSetScissor CmdSetScissor; PFN_vkCmdPushConstants CmdPushConstants; +bool _try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy) { + for (uint32_t i=0; ilastCtx; while (ctx != NULL){ diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index 202a0e2..b317841 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -92,6 +92,8 @@ typedef struct _vkvg_device_t{ int hdpi, /**< only used for FreeType fonts and svg loading */ vdpi; + VkhDevice vkhDev; /**< old VkhDev created during vulkan context creation by @ref vkvg_device_create. */ + VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */ VkSampleCountFlags samples; /**< samples count common to all surfaces */ bool deferredResolve; /**< if true, resolve only on context destruction and set as source */ @@ -101,6 +103,7 @@ typedef struct _vkvg_device_t{ VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/ }vkvg_device; +bool _try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy); bool _init_function_pointers (VkvgDevice dev); void _create_empty_texture (VkvgDevice dev, VkFormat format, VkImageTiling tiling); void _get_best_image_tiling (VkvgDevice dev, VkFormat format, VkImageTiling* pTiling); diff --git a/tests/common/test.c b/tests/common/test.c index f0d47ec..645948b 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -149,7 +149,7 @@ void init_test (uint32_t width, uint32_t height){ bool deferredResolve = false; - device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); + device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); surf = vkvg_surface_create(device, width, height); vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height); @@ -388,7 +388,7 @@ void perform_test_offscreen (void(*testfunc)(void), const char *testName, int ar VkhDevice dev = vkh_device_create(app, pi, &device_info); - device = vkvg_device_create_multisample(vkh_app_get_inst(app), dev->phy, dev->dev, pi->gQueue, 0, samples, deferredResolve); + device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(app), dev->phy, dev->dev, pi->gQueue, 0, samples, deferredResolve); //vkvg_device_set_dpy(device, 96, 96); vkh_app_free_phyinfos (phyCount, phys); @@ -462,7 +462,7 @@ void perform_test (void(*testfunc)(void), const char *testName, int argc, char* bool deferredResolve = false; - device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); + device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve); vkvg_device_set_dpy(device, 96, 96); diff --git a/tests/offscreen.c b/tests/offscreen.c new file mode 100644 index 0000000..095baa0 --- /dev/null +++ b/tests/offscreen.c @@ -0,0 +1,20 @@ +#include "vkvg.h" + +int main(int argc, char *argv[]) { + VkvgDevice dev = vkvg_device_create(VK_SAMPLE_COUNT_1_BIT, false); + VkvgSurface surf = vkvg_surface_create(dev, 512,512); + VkvgContext ctx = vkvg_create(surf); + + vkvg_clear(ctx); + vkvg_rectangle(ctx, 10, 10, 250, 200); + vkvg_set_source_rgb(ctx, 1, 0, 0); + vkvg_fill(ctx); + + vkvg_destroy(ctx); + + vkvg_surface_write_to_png(surf, "offscreen.png"); + vkvg_surface_destroy(surf); + + vkvg_device_destroy(dev); + return 0; +} diff --git a/vkh b/vkh index 7dfff1a..b15e2e5 160000 --- a/vkh +++ b/vkh @@ -1 +1 @@ -Subproject commit 7dfff1a2e601e142583c122c9f716578d8e85039 +Subproject commit b15e2e52f6eb74e72f31391dbcf007a9e5ce3815 -- 2.47.3