]> O.S.I.I.S - jp/vkhelpers.git/commitdiff
quick howto + improve available functions
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 13 May 2020 01:16:02 +0000 (03:16 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 13 May 2020 01:16:02 +0000 (03:16 +0200)
README.md
include/vkh.h
src/vkh_phyinfo.c
src/vkh_phyinfo.h

index 186d4a4a82b3010ccaa3f480509e3a14eaa6db39..8815d809853dd47af4ef0f80c9d1af9e0a28d365 100644 (file)
--- a/README.md
+++ b/README.md
 </p>
 </h1>
 
-### What is vkh?
+Small personal helper library for [Vulkan](https://www.khronos.org/vulkan/) usage in **c**.
+Simplify several common tasks, as image or buffers handling, swapchain initialization, etc.
 
-**vkh** is a multiplatform helper library for [Vulkan](https://www.khronos.org/vulkan/) written in **c**.
-vkh main goal is to offer an api which will ease the development of wrappers for higher level languages.
-No additional library except vulkan is required.
+**vkh**  is used by [vkvg] internally and also to speed up vulkan context creation in samples.
 
-### Current status:
-
-Early development stage, api may change frequently.
-
-### Building
+### Building from source
 
 ```bash
 git clone https://github.com/jpbruyere/vkhelpers.git
@@ -39,4 +34,89 @@ make && make install
 fields of internal structures, add also `${CMAKE_CURRENT_SOURCE_DIR}/vkhelpers/src`.
 - to link vkh staticaly, add to **TARGET_LINK_LIBRARIES** `vkh_static` or `vkh_shared` to link it as a shared library.
 
+### Quick howto:
+
+##### Create instance
+```c
+#include "vkh.h"
+#include "vkh_phyinfo.h"
+
+void init_vulkan () {
+  const char* layers [] = {"VK_LAYER_KHRONOS_validation"};
+  const char* exts [] = {"VK_EXT_debug_utils"};
+       
+  VkhApp app = vkh_app_create ("appname", 1, layers, 1, exts);
+```
+##### Select physical device
+
+**VkhPhyInfo** is an helper structure that will store common usefull physical device informations, queues flags, memory properties in a single call for all the device present on the machine.
+```c
+   VkhPhyInfo* phys = vkh_app_get_phyinfos (e->app, &phyCount, surf);
+```
+Once you have an array of VkhPhyInfo's, you have several functions to inspect available devices:
+```c
+for (uint i=0; i<phyCount; i++) {
+  //check VkPhysicalDeviceProperties
+  VkPhysicalDeviceProperties pdp = vkh_phyinfo_get_properties (phys[i]);
+  //get VkPhysicalDeviceMemoryProperties
+  VkPhysicalDeviceMemoryProperties mp = vkh_phyinfo_get_memory_properties (phys[i]);
+  //get queue properties
+  VkQueueFamilyProperties* vkh_phyinfo_get_queues_props(phys[i], &qCount);
+```
+VkhPhyInfo structure has the array of **VkQueueFamilyProperties** that has already be parsed two times to detect available queues types. First vkh will try to find a dedicated queue for each queue types (Graphic, Transfer, Compute) and if a type has no dedicated candidate, it will try to find a queue with the requested flag among others. Also if you submit a valid **VkSurfaceKHR** to `vkh_app_get_phyinfos`, presentation support will be queried for all graphic queues. The result of this search may be fetched with:
+```c
+vkh_phyinfo_get_queue_fam_indices (phy, &presentQ, &graphQ, &transQ, &compQ);
+```
+vkh has one function per queue type that use the result of this search. They may be safely called for checking queue availability, it will return false on failure. On success, the queue count of the `VkQueueFamilyProperties` of phyinfo will be decreased.
+```c
+       if (vkh_phyinfo_create_presentable_queues (pi, 1, qPriorities, &pQueueInfos[qCount]))
+               qCount++;
+       if (vkh_phyinfo_create_compute_queues (pi, 1, qPriorities, &pQueueInfos[qCount]))
+               qCount++;
+       if (vkh_phyinfo_create_transfer_queues (pi, 1, qPriorities, &pQueueInfos[qCount]))
+               qCount++;
+```
+To override the vkh default queue selection, create queues with your own family index:
+```c
+vkh_phyinfo_create_queues (phy, qFam, queueCount, priorities, &qInfo) {
+```
+Be aware that the queue count of the vkhinfo structure is decreased to keep track of remaining queues.
+PhyInfo pointer has to be freed when no longuer in use. Usualy at the end of the vulkan initialization.
+```c
+vkh_app_free_phyinfos  (phyCount, phys);
+```
+##### Create Logical Device
+
+```c
+char const * dex [] = {"VK_KHR_swapchain"};
+VkPhysicalDeviceFeatures enabledFeatures = { .fillModeNonSolid = true };
+VkDeviceCreateInfo device_info = {
+  .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+  .queueCreateInfoCount = qCount,
+  .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos,
+  .enabledExtensionCount = enabledExtsCount,
+  .ppEnabledExtensionNames = dex,
+  .pEnabledFeatures = &enabledFeatures};
+VkhDevice dev = vkh_device_create(e->app, pi, &device_info);
+```
+##### The Presenter
+VkhPresenter will help getting rapidly something on screen, it handles the swapchain.
+```c
+VkhPresenter present = vkh_presenter_create (dev, pi->pQueue, surf, width, height, VK_FORMAT_B8G8R8A8_UNORM, VK_PRESENT_MODE_MAILBOX_KHR);
+//create a blitting command buffer per swapchain images with
+vkh_presenter_build_blit_cmd (present, vkvg_surface_get_vk_image(surf), width, height);
+while (running) {
+  if (!vkh_presenter_draw (present))
+    //on draw failed, swapchain is automatically rebuilt
+    vkh_presenter_build_blit_cmd (present, vkvg_surface_get_vk_image(surf), width, height);
+}
+```
+##### Creating Images
+TODO
+##### Creating Buffers
+TODO
+
+
+
+
 
index 3e4f2e8e75125c1bd4be2f7bf120248f731d462f..5bca0c88f304f68cb8bdb28ea5e4a7477a2da0a4 100644 (file)
@@ -46,12 +46,12 @@ typedef enum VmaMemoryUsage VmaMemoryUsage;
 
 #define VK_CHECK_RESULT(f)                                                                                                                                                             \
 {                                                                                                                                                                                                              \
-    VkResult res = (f);                                                                                                                                                                        \
-    if (res != VK_SUCCESS)                                                                                                                                                             \
-    {                                                                                                                                                                                                  \
-        fprintf(stderr, "Fatal : VkResult is %d in %s at line %d\n", res,  __FILE__, __LINE__); \
-        assert(res == VK_SUCCESS);                                                                                                                                             \
-    }                                                                                                                                                                                                  \
+       VkResult res = (f);                                                                                                                                                                     \
+       if (res != VK_SUCCESS)                                                                                                                                                          \
+       {                                                                                                                                                                                                       \
+               fprintf(stderr, "Fatal : VkResult is %d in %s at line %d\n", res,  __FILE__, __LINE__); \
+               assert(res == VK_SUCCESS);                                                                                                                                              \
+       }                                                                                                                                                                                                       \
 }
 
 typedef struct _vkh_app_t*             VkhApp;
@@ -72,20 +72,28 @@ VkPhysicalDevice    vkh_app_select_phy  (VkhApp app, VkPhysicalDeviceType prefer
 VkhPhyInfo*         vkh_app_get_phyinfos    (VkhApp app, uint32_t* count, VkSurfaceKHR surface);
 void                vkh_app_free_phyinfos   (uint32_t count, VkhPhyInfo* infos);
 void                vkh_app_enable_debug_messenger (VkhApp app, VkDebugUtilsMessageTypeFlagsEXT typeFlags,
-                                                    VkDebugUtilsMessageSeverityFlagsEXT severityFlags,
-                                                    PFN_vkDebugUtilsMessengerCallbackEXT callback);
+                                                                                                       VkDebugUtilsMessageSeverityFlagsEXT severityFlags,
+                                                                                                       PFN_vkDebugUtilsMessengerCallbackEXT callback);
 
-VkPhysicalDeviceProperties          vkh_app_get_phy_properties          (VkhApp app, uint32_t phyIndex);
+VkPhysicalDeviceProperties          vkh_app_get_phy_properties (VkhApp app, uint32_t phyIndex);
 
 /*************
  * VkhPhy    *
  *************/
-VkhPhyInfo          vkh_phyinfo_create  (VkPhysicalDevice phy, VkSurfaceKHR surface);
-void                vkh_phyinfo_destroy (VkhPhyInfo phy);
+VkhPhyInfo          vkh_phyinfo_create         (VkPhysicalDevice phy, VkSurfaceKHR surface);
+void                vkh_phyinfo_destroy                (VkhPhyInfo phy);
 
 VkPhysicalDeviceProperties          vkh_phyinfo_get_properties          (VkhPhyInfo phy);
 VkPhysicalDeviceMemoryProperties    vkh_phyinfo_get_memory_properties   (VkhPhyInfo phy);
-uint32_t                            vkh_phy_info_get_graphic_queue_index(VkhPhyInfo phy);
+
+void vkh_phyinfo_get_queue_fam_indices         (VkhPhyInfo phy, int* pQueue, int* gQueue, int* tQueue, int* cQueue);
+VkQueueFamilyProperties* vkh_phyinfo_get_queues_props(VkhPhyInfo phy, uint32_t* qCount);
+
+bool vkh_phyinfo_create_queues   (VkhPhyInfo phy, int qFam, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo);
+bool vkh_phyinfo_create_presentable_queues     (VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo);
+bool phy_info_create_graphic_queues                    (VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo);
+bool vkh_phyinfo_create_transfer_queues                (VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo);
+bool vkh_phyinfo_create_compute_queues         (VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo);
 
 /*************
  * VkhDevice *
@@ -98,15 +106,15 @@ void                vkh_device_init_debug_utils (VkhDevice dev);
 void vkh_device_set_object_name (VkhDevice dev, VkObjectType objectType, uint64_t handle, const char *name);
 
 VkSampler vkh_device_create_sampler (VkhDevice dev, VkFilter magFilter, VkFilter minFilter,
-                               VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode);
+                                                          VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode);
 void vkh_device_destroy_sampler (VkhDevice dev, VkSampler sampler);
 
 /****************
  * VkhPresenter *
  ****************/
 VkhPresenter vkh_presenter_create (VkhDevice dev, uint32_t presentQueueFamIdx, VkSurfaceKHR surface,
-                                   uint32_t width, uint32_t height,
-                                   VkFormat preferedFormat, VkPresentModeKHR presentMode);
+                                                                  uint32_t width, uint32_t height,
+                                                                  VkFormat preferedFormat, VkPresentModeKHR presentMode);
 void        vkh_presenter_destroy (VkhPresenter r);
 bool        vkh_presenter_draw    (VkhPresenter r);
 bool        vkh_presenter_acquireNextImage  (VkhPresenter r, VkFence fence, VkSemaphore semaphore);
@@ -117,21 +125,21 @@ void        vkh_presenter_create_swapchain  (VkhPresenter r);
  ************/
 VkhImage vkh_image_import       (VkhDevice pDev, VkImage vkImg, VkFormat format, uint32_t width, uint32_t height);
 VkhImage vkh_image_create       (VkhDevice pDev, VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling,
-                                    VmaMemoryUsage memprops,   VkImageUsageFlags usage);
+                                                                       VmaMemoryUsage memprops,        VkImageUsageFlags usage);
 VkhImage vkh_image_ms_create    (VkhDevice pDev, VkFormat format, VkSampleCountFlagBits num_samples, uint32_t width, uint32_t height,
-                                    VmaMemoryUsage memprops,   VkImageUsageFlags usage);
+                                                                       VmaMemoryUsage memprops,        VkImageUsageFlags usage);
 VkhImage vkh_tex2d_array_create (VkhDevice pDev, VkFormat format, uint32_t width, uint32_t height, uint32_t layers,
-                                    VmaMemoryUsage memprops, VkImageUsageFlags usage);
+                                                                       VmaMemoryUsage memprops, VkImageUsageFlags usage);
 void vkh_image_set_sampler      (VkhImage img, VkSampler sampler);
 void vkh_image_create_descriptor(VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags, VkFilter magFilter, VkFilter minFilter,
-                                    VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode);
+                                                                       VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode);
 void vkh_image_create_view      (VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags);
 void vkh_image_create_sampler   (VkhImage img, VkFilter magFilter, VkFilter minFilter,
-                                    VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode);
+                                                                       VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode);
 void vkh_image_set_layout       (VkCommandBuffer cmdBuff, VkhImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout,
-                                    VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
+                                                                       VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
 void vkh_image_set_layout_subres(VkCommandBuffer cmdBuff, VkhImage image, VkImageSubresourceRange subresourceRange, VkImageLayout old_image_layout,
-                                    VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
+                                                                       VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
 void vkh_image_destroy_sampler  (VkhImage img);
 void vkh_image_destroy          (VkhImage img);
 void* vkh_image_map             (VkhImage img);
@@ -148,7 +156,7 @@ VkDescriptorImageInfo   vkh_image_get_descriptor(VkhImage img, VkImageLayout ima
  * VkhBuffer *
  *************/
 VkhBuffer   vkh_buffer_create   (VkhDevice pDev, VkBufferUsageFlags usage,
-                                    VmaMemoryUsage memprops, VkDeviceSize size);
+                                                                       VmaMemoryUsage memprops, VkDeviceSize size);
 void        vkh_buffer_destroy  (VkhBuffer buff);
 VkResult    vkh_buffer_map      (VkhBuffer buff);
 void        vkh_buffer_unmap    (VkhBuffer buff);
@@ -168,7 +176,7 @@ void vkh_cmd_begin  (VkCommandBuffer cmdBuff, VkCommandBufferUsageFlags flags);
 void vkh_cmd_end    (VkCommandBuffer cmdBuff);
 void vkh_cmd_submit (VkhQueue queue, VkCommandBuffer *pCmdBuff, VkFence fence);
 void vkh_cmd_submit_with_semaphores(VkhQueue queue, VkCommandBuffer *pCmdBuff, VkSemaphore waitSemaphore,
-                                    VkSemaphore signalSemaphore, VkFence fence);
+                                                                       VkSemaphore signalSemaphore, VkFence fence);
 
 void vkh_cmd_label_start   (VkCommandBuffer cmd, const char* name, const float color[]);
 void vkh_cmd_label_end     (VkCommandBuffer cmd);
@@ -177,16 +185,16 @@ void vkh_cmd_label_insert  (VkCommandBuffer cmd, const char* name, const float c
 VkShaderModule vkh_load_module(VkDevice dev, const char* path);
 
 bool        vkh_memory_type_from_properties(VkPhysicalDeviceMemoryProperties* memory_properties, uint32_t typeBits,
-                                        VkFlags requirements_mask, uint32_t *typeIndex);
+                                                                               VkFlags requirements_mask, uint32_t *typeIndex);
 char *      read_spv(const char *filename, size_t *psize);
 uint32_t*   readFile(uint32_t* length, const char* filename);
 
 void dumpLayerExts ();
 
 void        set_image_layout(VkCommandBuffer cmdBuff, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout,
-                      VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
+                                         VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
 void        set_image_layout_subres(VkCommandBuffer cmdBuff, VkImage image, VkImageSubresourceRange subresourceRange, VkImageLayout old_image_layout,
-                      VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
+                                         VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
 /////////////////////
 VkhQueue    vkh_queue_create    (VkhDevice dev, uint32_t familyIndex, uint32_t qIndex, VkQueueFlags flags);
 void        vkh_queue_destroy   (VkhQueue queue);
index d97a126fca45cd71d217ff016191f2b701339c5f..5d1d5c6e28c7b482702849e470332c3227792bf7 100644 (file)
 
 
 VkhPhyInfo vkh_phyinfo_create (VkPhysicalDevice phy, VkSurfaceKHR surface) {
-    VkhPhyInfo pi = (vkh_phy_t*)calloc(1, sizeof(vkh_phy_t));
-    pi->phy = phy;
+       VkhPhyInfo pi = (vkh_phy_t*)calloc(1, sizeof(vkh_phy_t));
+       pi->phy = phy;
 
-    vkGetPhysicalDeviceProperties (phy, &pi->properties);
-    vkGetPhysicalDeviceMemoryProperties (phy, &pi->memProps);
+       vkGetPhysicalDeviceProperties (phy, &pi->properties);
+       vkGetPhysicalDeviceMemoryProperties (phy, &pi->memProps);
 
-    vkGetPhysicalDeviceQueueFamilyProperties (phy, &pi->queueCount, NULL);
-    pi->queues = (VkQueueFamilyProperties*)malloc(pi->queueCount * sizeof(VkQueueFamilyProperties));
-    vkGetPhysicalDeviceQueueFamilyProperties (phy, &pi->queueCount, pi->queues);
+       vkGetPhysicalDeviceQueueFamilyProperties (phy, &pi->queueCount, NULL);
+       pi->queues = (VkQueueFamilyProperties*)malloc(pi->queueCount * sizeof(VkQueueFamilyProperties));
+       vkGetPhysicalDeviceQueueFamilyProperties (phy, &pi->queueCount, pi->queues);
 
-    //identify dedicated queues
+       //identify dedicated queues
 
-    pi->cQueue = -1;
-    pi->gQueue = -1;
-    pi->tQueue = -1;
-    pi->pQueue = -1;
+       pi->cQueue = -1;
+       pi->gQueue = -1;
+       pi->tQueue = -1;
+       pi->pQueue = -1;
 
-    //try to find dedicated queues first
-    for (int j=0; j<pi->queueCount; j++){
-        VkBool32 present = VK_FALSE;
-        switch (pi->queues[j].queueFlags) {
-        case VK_QUEUE_GRAPHICS_BIT:
-            if (surface)
-                vkGetPhysicalDeviceSurfaceSupportKHR(phy, j, surface, &present);
-            if (present){
-                if (pi->pQueue<0)
-                    pi->pQueue = j;
-            }else if (pi->gQueue<0)
-                pi->gQueue = j;
-            break;
-        case VK_QUEUE_COMPUTE_BIT:
-            if (pi->cQueue<0)
-                pi->cQueue = j;
-            break;
-        case VK_QUEUE_TRANSFER_BIT:
-            if (pi->tQueue<0)
-                pi->tQueue = j;
-            break;
-        }
-    }
-    //try to find suitable queue if no dedicated one found
-    for (int j=0; j<pi->queueCount; j++){
-        if (pi->queues[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
-            VkBool32 present;
-            if (surface)
-                vkGetPhysicalDeviceSurfaceSupportKHR(phy, j, surface, &present);
-            //printf ("surf=%d, q=%d, present=%d\n",surface,j,present);
-            if (present){
-                if (pi->pQueue<0)
-                    pi->pQueue = j;
-            }else if (pi->gQueue<0)
-                pi->gQueue = j;
-        }
-        if ((pi->queues[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) && (pi->gQueue < 0))
-            pi->gQueue = j;
-        if ((pi->queues[j].queueFlags & VK_QUEUE_COMPUTE_BIT) && (pi->cQueue < 0))
-            pi->cQueue = j;
-        if ((pi->queues[j].queueFlags & VK_QUEUE_TRANSFER_BIT) && (pi->tQueue < 0))
-            pi->tQueue = j;
-    }
+       //try to find dedicated queues first
+       for (int j=0; j<pi->queueCount; j++){
+               VkBool32 present = VK_FALSE;
+               switch (pi->queues[j].queueFlags) {
+               case VK_QUEUE_GRAPHICS_BIT:
+                       if (surface)
+                               vkGetPhysicalDeviceSurfaceSupportKHR(phy, j, surface, &present);
+                       if (present){
+                               if (pi->pQueue<0)
+                                       pi->pQueue = j;
+                       }else if (pi->gQueue<0)
+                               pi->gQueue = j;
+                       break;
+               case VK_QUEUE_COMPUTE_BIT:
+                       if (pi->cQueue<0)
+                               pi->cQueue = j;
+                       break;
+               case VK_QUEUE_TRANSFER_BIT:
+                       if (pi->tQueue<0)
+                               pi->tQueue = j;
+                       break;
+               }
+       }
+       //try to find suitable queue if no dedicated one found
+       for (uint j=0; j<pi->queueCount; j++){
+               if (pi->queues[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+                       VkBool32 present;
+                       if (surface)
+                               vkGetPhysicalDeviceSurfaceSupportKHR(phy, j, surface, &present);
+                       //printf ("surf=%d, q=%d, present=%d\n",surface,j,present);
+                       if (present){
+                               if (pi->pQueue<0)
+                                       pi->pQueue = j;
+                       }else if (pi->gQueue<0)
+                               pi->gQueue = j;
+               }
+               if ((pi->queues[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) && (pi->gQueue < 0))
+                       pi->gQueue = j;
+               if ((pi->queues[j].queueFlags & VK_QUEUE_COMPUTE_BIT) && (pi->cQueue < 0))
+                       pi->cQueue = j;
+               if ((pi->queues[j].queueFlags & VK_QUEUE_TRANSFER_BIT) && (pi->tQueue < 0))
+                       pi->tQueue = j;
+       }
 
-    return pi;
+       return pi;
 }
 
 void vkh_phyinfo_destroy (VkhPhyInfo phy) {
 
-    free(phy->queues);
-    free(phy);
+       free(phy->queues);
+       free(phy);
 }
 
-void vkh_phyinfo_select_queue (VkhPhyInfo phy, uint32_t qIndex, float* priorities) {
-
-}
 VkPhysicalDeviceProperties vkh_phyinfo_get_properties (VkhPhyInfo phy) {
-    return phy->properties;
+       return phy->properties;
 }
 VkPhysicalDeviceMemoryProperties vkh_phyinfo_get_memory_properties (VkhPhyInfo phy) {
-    return phy->memProps;
+       return phy->memProps;
+}
+
+void vkh_phyinfo_get_queue_fam_indices (VkhPhyInfo phy, int* pQueue, int* gQueue, int* tQueue, int* cQueue) {
+       *pQueue = phy->pQueue;
+       *gQueue = phy->gQueue;
+       *tQueue = phy->tQueue;
+       *cQueue = phy->cQueue;
+}
+VkQueueFamilyProperties* vkh_phyinfo_get_queues_props(VkhPhyInfo phy, uint32_t* qCount) {
+       *qCount = phy->queueCount;
+       return phy->queues;
+}
+bool vkh_phyinfo_create_queues (VkhPhyInfo phy, int qFam, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo) {
+       qInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       if (phy->queues[qFam].queueCount < queueCount)
+               fprintf(stderr, "Request %d queues of family %d, but only %d available\n", queueCount, qFam, phy->queues[qFam].queueCount);
+       else {
+               qInfo->queueCount = queueCount,
+               qInfo->queueFamilyIndex = qFam,
+               qInfo->pQueuePriorities = queue_priorities;
+               phy->queues[qFam].queueCount -= queueCount;
+               return true;
+       }
+       return false;
+}
+bool vkh_phyinfo_create_presentable_queues (VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo) {
+       qInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       if (phy->pQueue < 0)
+               perror("No queue with presentable support found");
+       else if (phy->queues[phy->pQueue].queueCount < queueCount)
+               fprintf(stderr, "Request %d queues of family %d, but only %d available\n", queueCount, phy->pQueue, phy->queues[phy->pQueue].queueCount);
+       else {
+               qInfo->queueCount = queueCount,
+               qInfo->queueFamilyIndex = phy->pQueue,
+               qInfo->pQueuePriorities = queue_priorities;
+               phy->queues[phy->pQueue].queueCount -= queueCount;
+               return true;
+       }
+       return false;
+}
+bool vkh_phyinfo_create_transfer_queues (VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo) {
+       qInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       if (phy->tQueue < 0)
+               perror("No transfer queue found");
+       else if (phy->queues[phy->tQueue].queueCount < queueCount)
+               fprintf(stderr, "Request %d transfer queues of family %d, but only %d available\n", queueCount, phy->tQueue, phy->queues[phy->tQueue].queueCount);
+       else {
+               qInfo->queueCount = queueCount;
+               qInfo->queueFamilyIndex = phy->tQueue;
+               qInfo->pQueuePriorities = queue_priorities;
+               phy->queues[phy->tQueue].queueCount -= queueCount;
+               return true;
+       }
+       return false;
+}
+bool vkh_phyinfo_create_compute_queues(VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo) {
+       qInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       if (phy->cQueue < 0)
+               perror("No compute queue found");
+       else if (phy->queues[phy->cQueue].queueCount < queueCount)
+               fprintf(stderr, "Request %d compute queues of family %d, but only %d available\n", queueCount, phy->cQueue, phy->queues[phy->cQueue].queueCount);
+       else {
+               qInfo->queueCount = queueCount,
+               qInfo->queueFamilyIndex = phy->cQueue,
+               qInfo->pQueuePriorities = queue_priorities;
+               phy->queues[phy->cQueue].queueCount -= queueCount;
+               return true;
+       }
+       return false;
 }
-uint32_t vkh_phy_info_get_graphic_queue_index (VkhPhyInfo phy) {
-    return (uint32_t)phy->gQueue;
+bool vkh_phy_info_create_graphic_queues (VkhPhyInfo phy, uint32_t queueCount, const float* queue_priorities, VkDeviceQueueCreateInfo* const qInfo) {
+       qInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+       if (phy->gQueue < 0)
+               perror("No graphic queue found");
+       else if (phy->queues[phy->gQueue].queueCount < queueCount)
+               fprintf(stderr, "Request %d graphic queues of family %d, but only %d available\n", queueCount, phy->gQueue, phy->queues[phy->gQueue].queueCount);
+       else {
+               qInfo->queueCount = queueCount,
+               qInfo->queueFamilyIndex = phy->gQueue,
+               qInfo->pQueuePriorities = queue_priorities;
+               phy->queues[phy->gQueue].queueCount -= queueCount;
+               return true;
+       }
+       return false;
 }
index 75c987c54dd025f48dc06695a277020babb72517..c3e10769924d43c2b7378bc31f3bd89bedba3c77 100644 (file)
@@ -29,18 +29,18 @@ extern "C" {
 #include "vkh.h"
 
 typedef struct _vkh_phy_t{
-    VkPhysicalDevice                    phy;
-    VkPhysicalDeviceMemoryProperties    memProps;
-    VkPhysicalDeviceProperties          properties;
-    VkQueueFamilyProperties*            queues;
-    uint32_t                            queueCount;
-    int                                 cQueue;//compute
-    int                                 gQueue;//graphic
-    int                                 tQueue;//transfer
-    int                                 pQueue;//presentation
+       VkPhysicalDevice                    phy;
+       VkPhysicalDeviceMemoryProperties    memProps;
+       VkPhysicalDeviceProperties          properties;
+       VkQueueFamilyProperties*            queues;
+       uint32_t                            queueCount;
+       int                                 cQueue;//compute
+       int                                 gQueue;//graphic
+       int                                 tQueue;//transfer
+       int                                 pQueue;//presentation
 
-    uint32_t                            qCreateInfosCount;
-    VkDeviceQueueCreateInfo*            qCreateInfos;
+       uint32_t                            qCreateInfosCount;
+       VkDeviceQueueCreateInfo*            qCreateInfos;
 }vkh_phy_t;
 #ifdef __cplusplus
 }