--- /dev/null
+MIT License
+
+Copyright (c) [2018] [Jean-Philippe Bruyère]
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
-# vkhelpers
+<h1 align="center">
+ <br>
+ <br>
+ Vulkan Helpers
+ <br>
+<p align="center">
+ <a href="https://www.paypal.me/GrandTetraSoftware">
+ <img src="https://img.shields.io/badge/Donate-PayPal-green.svg">
+ </a>
+</p>
+</h1>
+
+### What is vkh?
+
+**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.
+
+### Current status:
+
+Early development stage, api may changed frequently.
+
+### Building
+
+```bash
+git clone https://github.com/jpbruyere/vkhelpers.git
+cd vkhelpers
+mkdir build
+cd build
+cmake ..
+make && make install
+```
+
+### Adding vkh to your CMake project
+
+- clone vkh as a subdirectory of your root dir.
+- in your main CMakeFile, add `add_subdirectory (vkhelpers)`
+- add to your **TARGET_INCLUDE_DIRECTORIES** `${CMAKE_CURRENT_SOURCE_DIR}/vkhelpers/include` and if you want to bypass opaque pointers and be able to address
+fiels of internal structures of vkh, 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.
+
+
typedef struct _vkh_device_t* VkhDevice;
typedef struct _vkh_image_t* VkhImage;
typedef struct _vkh_buffer_t* VkhBuffer;
+typedef struct _vkh_queue_t* VkhQueue;
//typedef struct _vkh_presenter_t* VkhPresenter;
///////////////////
-VkhApp vkh_app_create (const char* app_name, const char* extentions[], int ext_count);
+VkhApp vkh_app_create (const char* app_name, int ext_count, const char* extentions[]);
void vkh_app_destroy (VkhApp app);
VkInstance vkh_app_get_inst (VkhApp app);
VkPhysicalDevice vkh_app_select_phy (VkhApp app, VkPhysicalDeviceType preferedPhyType);
void vkh_cmd_submit_with_semaphores(VkQueue queue, VkCommandBuffer *pCmdBuff, VkSemaphore waitSemaphore,
VkSemaphore signalSemaphore, VkFence fence);
-VkPhysicalDevice vkh_find_phy (VkInstance inst, VkPhysicalDeviceType phyType);
-
VkShaderModule vkh_load_module(VkDevice dev, const char* path);
bool memory_type_from_properties(VkPhysicalDeviceMemoryProperties* memory_properties, uint32_t typeBits,
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);
+/////////////////////
+VkhQueue vkh_queue_create (VkhDevice dev, uint32_t familyIndex, uint32_t qIndex, VkQueueFlags flags);
+void vkh_queue_destroy (VkhQueue queue);
+VkhQueue vkh_queue_find (VkhDevice dev, VkQueueFlags flags);
+/////////////////////
#endif
#define ENGINE_NAME "vkheplers"
#define ENGINE_VERSION 1
-VkhApp vkh_app_create (const char* app_name, const char* extentions[], int ext_count) {
+VkhApp vkh_app_create (const char* app_name, int ext_count, const char* extentions[]) {
VkhApp app = (VkhApp)malloc(sizeof(vkh_app_t));
VkApplicationInfo infos = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.ppEnabledLayerNames = enabledLayers };
VK_CHECK_RESULT(vkCreateInstance (&inst_info, NULL, &app->inst));
+
+ VK_CHECK_RESULT(vkEnumeratePhysicalDevices (app->inst, &app->phyCount, NULL));
+
return app;
}
}
VkPhysicalDevice vkh_app_select_phy (VkhApp app, VkPhysicalDeviceType preferedPhyType) {
- uint32_t gpu_count = 0;
-
- VK_CHECK_RESULT(vkEnumeratePhysicalDevices (app->inst, &gpu_count, NULL));
-
- VkPhysicalDevice phys[gpu_count];
-
- VK_CHECK_RESULT(vkEnumeratePhysicalDevices (app->inst, &gpu_count, &phys));
+ VkPhysicalDevice phys[app->phyCount];
+ VK_CHECK_RESULT(vkEnumeratePhysicalDevices (app->inst, &app->phyCount, &phys));
- if (gpu_count == 1)
+ if (app->phyCount == 1)
return phys[0];
- for (int i=0; i<gpu_count; i++){
+ for (int i=0; i<app->phyCount; i++){
VkPhysicalDeviceProperties phy;
vkGetPhysicalDeviceProperties (phys[i], &phy);
if (phy.deviceType & preferedPhyType){
typedef struct _vkh_app_t{
VkApplicationInfo infos;
VkInstance inst;
+ uint32_t phyCount;
}vkh_app_t;
#endif
VkDevice dev;
VkPhysicalDeviceMemoryProperties phyMemProps;
VkRenderPass renderPass;
-// VkPhysicalDevice phy;
-// VkDevice dev;
-
-// VkPhysicalDeviceMemoryProperties phyMemProps;
+ VkPhysicalDevice phy;
}vkh_device_t;
#endif
--- /dev/null
+#include "vkh_queue.h"
+#include "vkh_device.h"
+
+VkhQueue _init_queue (VkhDevice dev) {
+ VkhQueue q = (vkh_queue_t*)calloc(1, sizeof(vkh_queue_t));
+ q->dev = dev;
+ return q;
+}
+
+
+VkhQueue vkh_queue_create (VkhDevice dev, uint32_t familyIndex, uint32_t qIndex, VkQueueFlags flags) {
+ VkhQueue q = _init_queue (dev);
+ q->familyIndex = familyIndex;
+ vkGetDeviceQueue (dev->dev, familyIndex, qIndex, &q->queue);
+ return q;
+}
+
+VkhQueue vkh_queue_find (VkhDevice dev, VkQueueFlags flags) {
+ uint32_t qFamCount = 0;
+ vkGetPhysicalDeviceQueueFamilyProperties (dev->phy, &qFamCount, NULL);
+ VkQueueFamilyProperties qFams[qFamCount];
+ vkGetPhysicalDeviceQueueFamilyProperties (dev->phy, &qFamCount, qFams);
+
+ //first try to find dedicated queue
+ for (int i=0; i<qFamCount; i++){
+ if (qFams[i].queueFlags == flags)
+ return vkh_queue_create (dev, i, 0, qFams[i].queueFlags);
+ }
+ //if not found, get matching q
+ for (int i=0; i<qFamCount; i++){
+ if ((qFams[i].queueFlags & flags) == flags)
+ return vkh_queue_create (dev, i, 0, qFams[i].queueFlags);
+ }
+ return VK_NULL_HANDLE;
+}
+
+void vkh_queue_destroy (VkhQueue queue){
+ free (queue);
+}
--- /dev/null
+#ifndef VKH_QUEUE_H
+#define VKH_QUEUE_H
+
+#include "vkh.h"
+
+typedef struct _vkh_queue_t{
+ VkhDevice dev;
+ uint32_t familyIndex;
+ VkQueue queue;
+ VkQueueFlags flags;
+}vkh_queue_t;
+
+#endif
#include "vkh.h"
-VkPhysicalDevice vkh_find_phy (VkInstance inst, VkPhysicalDeviceType phyType) {
- uint32_t gpu_count = 0;
-
- VK_CHECK_RESULT(vkEnumeratePhysicalDevices (inst, &gpu_count, NULL));
- VkPhysicalDevice phys[gpu_count];
- VK_CHECK_RESULT(vkEnumeratePhysicalDevices (inst, &gpu_count, &phys));
-
- if (gpu_count == 1)
- return phys[0];
-
- for (int i=0; i<gpu_count; i++){
- VkPhysicalDeviceProperties phy;
- vkGetPhysicalDeviceProperties (phys[i], &phy);
- if (phy.deviceType & phyType){
- printf ("GPU: %s vulkan:%d.%d.%d driver:%d\n", phy.deviceName,
- phy.apiVersion>>22, phy.apiVersion>>12&2048, phy.apiVersion&8191,
- phy.driverVersion);
- return phys[i];
- }
- }
- fprintf (stderr, "No suitable GPU found\n");
- exit (-1);
-}
-
VkFence vkh_fence_create (VkDevice dev) {
VkFence fence;
VkFenceCreateInfo fenceInfo = { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,