</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
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
+
+
+
+
#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;
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 *
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);
************/
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);
* 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);
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);
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);
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;
}
#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
}