From: Jean-Philippe Bruyère Date: Fri, 8 Dec 2017 14:15:06 +0000 (+0100) Subject: first commit X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=5b03b4b6f663ed40e13c0c9ffe447fa020661164;p=jp%2Fvkhelpers.git first commit --- 5b03b4b6f663ed40e13c0c9ffe447fa020661164 diff --git a/README.md b/README.md new file mode 100644 index 0000000..78db504 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# vkhelpers diff --git a/vkh_buffer.c b/vkh_buffer.c new file mode 100644 index 0000000..8de3025 --- /dev/null +++ b/vkh_buffer.c @@ -0,0 +1,47 @@ +#include "vkh_buffer.h" +#include "vkhelpers.h" + +void vkh_buffer_create(vkh_device *pDev, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size, vkh_buffer* buff){ + buff->pDev = pDev; + VkBufferCreateInfo bufCreateInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .usage = usage, .size = size, .sharingMode = VK_SHARING_MODE_EXCLUSIVE}; + VK_CHECK_RESULT(vkCreateBuffer(pDev->vkDev, &bufCreateInfo, NULL, &buff->buffer)); + + VkMemoryRequirements memReq; + vkGetBufferMemoryRequirements(pDev->vkDev, buff->buffer, &memReq); + VkMemoryAllocateInfo memAllocInfo = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = memReq.size }; + assert(memory_type_from_properties(&pDev->phyMemProps, memReq.memoryTypeBits,memoryPropertyFlags, &memAllocInfo.memoryTypeIndex)); + VK_CHECK_RESULT(vkAllocateMemory(pDev->vkDev, &memAllocInfo, NULL, &buff->memory)); + + buff->alignment = memReq.alignment; + buff->size = memAllocInfo.allocationSize; + buff->usageFlags = usage; + buff->memoryPropertyFlags = memoryPropertyFlags; + + VK_CHECK_RESULT(vkh_buffer_bind(buff)); +} + +void vkh_buffer_destroy(vkh_buffer* buff){ + if (buff->buffer) + vkDestroyBuffer(buff->pDev->vkDev, buff->buffer, NULL); + if (buff->memory) + vkFreeMemory(buff->pDev->vkDev, buff->memory, NULL); +} + + +VkResult vkh_buffer_map(vkh_buffer* buff){ + return vkMapMemory(buff->pDev->vkDev, buff->memory, 0, VK_WHOLE_SIZE, 0, &buff->mapped); +} +void vkh_buffer_unmap(vkh_buffer* buff){ + if (!buff->mapped) + return; + vkUnmapMemory(buff->pDev->vkDev, buff->memory); + buff->mapped = NULL; +} + +VkResult vkh_buffer_bind(vkh_buffer* buff) +{ + return vkBindBufferMemory(buff->pDev->vkDev, buff->buffer, buff->memory, 0); +} diff --git a/vkh_buffer.h b/vkh_buffer.h new file mode 100644 index 0000000..68aa1a1 --- /dev/null +++ b/vkh_buffer.h @@ -0,0 +1,28 @@ +#ifndef VKH_BUFFER_H +#define VKH_BUFFER_H + +#include +#include "vkh_device.h" + +typedef struct vkh_buffer_t { + vkh_device* pDev; + VkBuffer buffer; + VkDeviceMemory memory; + VkDescriptorBufferInfo descriptor; + VkDeviceSize size; + VkDeviceSize alignment; + + VkBufferUsageFlags usageFlags; + VkMemoryPropertyFlags memoryPropertyFlags; + + void* mapped; +}vkh_buffer; + +void vkh_buffer_create (vkh_device *pDev, VkBufferUsageFlags usage, + VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size, vkh_buffer* buff); +void vkh_buffer_destroy (vkh_buffer* buff); +VkResult vkh_buffer_map (vkh_buffer* buff); +void vkh_buffer_unmap (vkh_buffer* buff); +VkResult vkh_buffer_bind (vkh_buffer* buff); + +#endif diff --git a/vkh_device.c b/vkh_device.c new file mode 100644 index 0000000..debfffb --- /dev/null +++ b/vkh_device.c @@ -0,0 +1 @@ +#include "vkh_device.h" diff --git a/vkh_device.h b/vkh_device.h new file mode 100644 index 0000000..cf36df3 --- /dev/null +++ b/vkh_device.h @@ -0,0 +1,12 @@ +#ifndef VKH_DEVICE_H +#define VKH_DEVICE_H + +#include "vkhelpers.h" + +typedef struct vkh_device_t{ + VkDevice vkDev; + VkPhysicalDeviceMemoryProperties phyMemProps; + VkRenderPass renderPass; +}vkh_device; + +#endif diff --git a/vkh_image.c b/vkh_image.c new file mode 100644 index 0000000..a0a14e8 --- /dev/null +++ b/vkh_image.c @@ -0,0 +1,90 @@ +#include "vkh_image.h" + +void _vkh_image_create (vkh_device *pDev, VkImageType imageType, + VkFormat format, uint32_t width, uint32_t height, + VkMemoryPropertyFlags memprops, VkImageUsageFlags usage, + VkSampleCountFlagBits samples, VkImageTiling tiling, + uint32_t mipLevels, uint32_t arrayLayers, + VkImageLayout layout, vkh_image* img){ + img->pDev = pDev; + img->width = width; + img->height = height; + + VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = imageType, + .tiling = tiling, + .initialLayout = layout, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .usage = usage, + .format = format, + .extent = {width,height,1}, + .mipLevels = mipLevels, + .arrayLayers = arrayLayers, + .samples = samples }; + + VK_CHECK_RESULT(vkCreateImage(pDev->vkDev, &image_info, NULL, &img->image)); + + img->infos = image_info; + + VkMemoryRequirements memReq; + vkGetImageMemoryRequirements(pDev->vkDev, img->image, &memReq); + VkMemoryAllocateInfo memAllocInfo = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = memReq.size }; + assert(memory_type_from_properties(&pDev->phyMemProps, memReq.memoryTypeBits, memprops,&memAllocInfo.memoryTypeIndex)); + VK_CHECK_RESULT(vkAllocateMemory(pDev->vkDev, &memAllocInfo, NULL, &img->memory)); + VK_CHECK_RESULT(vkBindImageMemory(pDev->vkDev, img->image, img->memory, 0)); +} +void vkh_tex2d_array_create (vkh_device *pDev, + VkFormat format, uint32_t width, uint32_t height, uint32_t layers, + VkMemoryPropertyFlags memprops, VkImageUsageFlags usage, vkh_image* img){ + _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage, + VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, 1, layers, VK_IMAGE_LAYOUT_PREINITIALIZED, img); +} + +void vkh_image_create (vkh_device *pDev, + VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling, + VkMemoryPropertyFlags memprops, + VkImageUsageFlags usage, VkImageLayout layout, vkh_image* img) +{ + _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage, + VK_SAMPLE_COUNT_1_BIT, tiling, 1, 1, layout, img); +} +void vkh_image_ms_create (vkh_device *pDev, + VkFormat format, VkSampleCountFlagBits num_samples, uint32_t width, uint32_t height, + VkMemoryPropertyFlags memprops, + VkImageUsageFlags usage, VkImageLayout layout, vkh_image* img){ + _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage, + num_samples, VK_IMAGE_TILING_OPTIMAL, 1, 1, layout, img); +} +void vkh_image_create_descriptor(vkh_image* img, VkImageViewType viewType, VkImageAspectFlags aspectFlags, VkFilter magFilter, + VkFilter minFilter, VkSamplerMipmapMode mipmapMode) +{ + img->pDescriptor = (VkDescriptorImageInfo*)malloc(sizeof(VkDescriptorImageInfo)); + img->pDescriptor->imageLayout = img->infos.initialLayout; + VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = img->image, + .viewType = viewType, + .format = img->infos.format, + .components = {VK_COMPONENT_SWIZZLE_R,VK_COMPONENT_SWIZZLE_G,VK_COMPONENT_SWIZZLE_B,VK_COMPONENT_SWIZZLE_A}, + .subresourceRange = {aspectFlags,0,1,0,img->infos.arrayLayers}}; + VK_CHECK_RESULT(vkCreateImageView(img->pDev->vkDev, &viewInfo, NULL, &img->pDescriptor->imageView)); + + VkSamplerCreateInfo samplerCreateInfo = { .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .maxAnisotropy = 1.0, + .magFilter = magFilter, + .minFilter = minFilter, + .mipmapMode = mipmapMode}; + VK_CHECK_RESULT(vkCreateSampler(img->pDev->vkDev, &samplerCreateInfo, NULL, &img->pDescriptor->sampler)); + +} +void vkh_image_destroy(vkh_image* img) +{ + if (img->pDescriptor != NULL){ + vkDestroyImageView(img->pDev->vkDev,img->pDescriptor->imageView,NULL); + if(img->pDescriptor->sampler != VK_NULL_HANDLE) + vkDestroySampler(img->pDev->vkDev,img->pDescriptor->sampler,NULL); + } + free(img->pDescriptor); + vkDestroyImage(img->pDev->vkDev,img->image,NULL); + vkFreeMemory(img->pDev->vkDev, img->memory, NULL); +} diff --git a/vkh_image.h b/vkh_image.h new file mode 100644 index 0000000..df87294 --- /dev/null +++ b/vkh_image.h @@ -0,0 +1,27 @@ +#ifndef VKH_IMAGE_H +#define VKH_IMAGE_H + +#include "vkhelpers.h" +#include "vkh_device.h" + +typedef struct vkh_image_t { + vkh_device* pDev; + VkImageCreateInfo infos; + uint32_t width, height; + VkImage image; + VkDeviceMemory memory; + VkDescriptorImageInfo* pDescriptor; +}vkh_image; + +void vkh_image_create (vkh_device* pDev, VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling, + VkMemoryPropertyFlags memprops, VkImageUsageFlags usage, VkImageLayout layout, vkh_image *img); +void vkh_image_ms_create (vkh_device *pDev, VkFormat format, VkSampleCountFlagBits num_samples, uint32_t width, uint32_t height, + VkMemoryPropertyFlags memprops, VkImageUsageFlags usage, VkImageLayout layout, vkh_image *img); + +void vkh_tex2d_array_create (vkh_device *pDev, VkFormat format, uint32_t width, uint32_t height, uint32_t layers, + VkMemoryPropertyFlags memprops, VkImageUsageFlags usage, vkh_image* img); + +void vkh_image_create_descriptor(vkh_image* img, VkImageViewType viewType, VkImageAspectFlags aspectFlags, VkFilter magFilter, VkFilter minFilter, + VkSamplerMipmapMode mipmapMode); +void vkh_image_destroy(vkh_image* img); +#endif diff --git a/vkh_presenter.c b/vkh_presenter.c new file mode 100644 index 0000000..851812a --- /dev/null +++ b/vkh_presenter.c @@ -0,0 +1,2 @@ +#include "vkh_presenter.h" + diff --git a/vkh_presenter.h b/vkh_presenter.h new file mode 100644 index 0000000..0a633e2 --- /dev/null +++ b/vkh_presenter.h @@ -0,0 +1,8 @@ +#ifndef VKH_PRESENTER_H +#define VKH_PRESENTER_H + +#include "vkhelpers.h" + + + +#endif diff --git a/vkhelpers.c b/vkhelpers.c new file mode 100644 index 0000000..ba3563c --- /dev/null +++ b/vkhelpers.c @@ -0,0 +1,259 @@ + +#include "vkhelpers.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)); + + for (int i=0; i>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, + .pNext = NULL, + .flags = 0 }; + VK_CHECK_RESULT(vkCreateFence(dev, &fenceInfo, NULL, &fence)); + return fence; +} +VkSemaphore vkh_semaphore_create (VkDevice dev) { + VkSemaphore semaphore; + VkSemaphoreCreateInfo info = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = NULL, + .flags = 0}; + VK_CHECK_RESULT(vkCreateSemaphore(dev, &info, NULL, &semaphore)); + return semaphore; +} +VkCommandPool vkh_cmd_pool_create (VkDevice dev, uint32_t qFamIndex, VkCommandPoolCreateFlags flags){ + VkCommandPool cmdPool; + VkCommandPoolCreateInfo cmd_pool_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .pNext = NULL, + .queueFamilyIndex = qFamIndex, + .flags = flags }; + VK_CHECK_RESULT (vkCreateCommandPool(dev, &cmd_pool_info, NULL, &cmdPool)); + return cmdPool; +} +VkCommandBuffer vkh_cmd_buff_create (VkDevice dev, VkCommandPool cmdPool, VkCommandBufferLevel level){ + VkCommandBuffer cmdBuff; + VkCommandBufferAllocateInfo cmd = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = NULL, + .commandPool = cmdPool, + .level = level, + .commandBufferCount = 1 }; + VK_CHECK_RESULT (vkAllocateCommandBuffers (dev, &cmd, &cmdBuff)); + return cmdBuff; +} + +void vkh_cmd_begin(VkCommandBuffer cmdBuff, VkCommandBufferUsageFlags flags) { + VkCommandBufferBeginInfo cmd_buf_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = NULL, + .flags = flags, + .pInheritanceInfo = NULL }; + + VK_CHECK_RESULT (vkBeginCommandBuffer (cmdBuff, &cmd_buf_info)); +} +void vkh_cmd_end(VkCommandBuffer cmdBuff){ + VK_CHECK_RESULT (vkEndCommandBuffer (cmdBuff)); +} +void vkh_cmd_submit(VkQueue queue, VkCommandBuffer *pCmdBuff, VkFence fence){ + VkSubmitInfo submit_info = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .commandBufferCount = 1, + .pCommandBuffers = pCmdBuff}; + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submit_info, fence)); +} +void vkh_cmd_submit_with_semaphores(VkQueue queue, VkCommandBuffer *pCmdBuff, VkSemaphore waitSemaphore, + VkSemaphore signalSemaphore, VkFence fence){ + + VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + VkSubmitInfo submit_info = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pWaitDstStageMask = &stageFlags, + .commandBufferCount = 1, + .pCommandBuffers = pCmdBuff}; + + if (waitSemaphore != VK_NULL_HANDLE){ + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = &waitSemaphore; + } + if (signalSemaphore != VK_NULL_HANDLE){ + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores= &signalSemaphore; + } + + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submit_info, fence)); +} + + + +void set_image_layout(VkCommandBuffer cmdBuff, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout, + VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages) { + VkImageMemoryBarrier image_memory_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .oldLayout = old_image_layout, + .newLayout = new_image_layout, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = image, + .subresourceRange = {aspectMask,0,1,0,1}}; + + switch (old_image_layout) { + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + image_memory_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + break; + + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + break; + + case VK_IMAGE_LAYOUT_PREINITIALIZED: + image_memory_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + break; + + default: + break; + } + + switch (new_image_layout) { + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + break; + + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + break; + + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; + + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + image_memory_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + break; + + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + image_memory_barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + break; + + default: + break; + } + + vkCmdPipelineBarrier(cmdBuff, src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, &image_memory_barrier); +} + +bool memory_type_from_properties(VkPhysicalDeviceMemoryProperties* memory_properties, uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex) { + // Search memtypes to find first index with those properties + for (uint32_t i = 0; i < memory_properties->memoryTypeCount; i++) { + if ((typeBits & 1) == 1) { + // Type is available, does it match user properties? + if ((memory_properties->memoryTypes[i].propertyFlags & requirements_mask) == requirements_mask) { + *typeIndex = i; + return true; + } + } + typeBits >>= 1; + } + // No memory types matched, return failure + return false; +} + +VkShaderModule vkh_load_module(VkDevice dev, const char* path){ + VkShaderModule module; + size_t filelength; + char* pCode = read_spv(path, &filelength); + VkShaderModuleCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pCode = pCode, + .codeSize = filelength }; + VK_CHECK_RESULT(vkCreateShaderModule(dev, &createInfo, NULL, &module)); + free (pCode); + //assert(module != VK_NULL_HANDLE); + return module; +} + +char *read_spv(const char *filename, size_t *psize) { + long int size; + size_t retval; + void *shader_code; + +#if (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK)) + filename =[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @(filename)].UTF8String; +#endif + + FILE *fp = fopen(filename, "rb"); + if (!fp) + return NULL; + + fseek(fp, 0L, SEEK_END); + size = ftell(fp); + + fseek(fp, 0L, SEEK_SET); + + shader_code = malloc(size); + retval = fread(shader_code, size, 1, fp); + assert(retval == 1); + + *psize = size; + + fclose(fp); + return shader_code; +} + +// Read file into array of bytes, and cast to uint32_t*, then return. +// The data has been padded, so that it fits into an array uint32_t. +uint32_t* readFile(uint32_t* length, const char* filename) { + + FILE* fp = fopen(filename, "rb"); + if (fp == 0) { + printf("Could not find or open file: %s\n", filename); + } + + // get file size. + fseek(fp, 0, SEEK_END); + long filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + long filesizepadded = (long)(ceil(filesize / 4.0)) * 4; + + // read file contents. + char *str = (char*)malloc(filesizepadded*sizeof(char)); + fread(str, filesize, sizeof(char), fp); + fclose(fp); + + // data padding. + for (int i = filesize; i < filesizepadded; i++) + str[i] = 0; + + *length = filesizepadded; + return (uint32_t *)str; +} + +void dumpLayerExts () { + printf ("Layers:\n"); + uint32_t instance_layer_count; + assert (vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL)==VK_SUCCESS); + if (instance_layer_count == 0) + return; + VkLayerProperties vk_props[instance_layer_count]; + assert (vkEnumerateInstanceLayerProperties(&instance_layer_count, vk_props)==VK_SUCCESS); + + for (uint32_t i = 0; i < instance_layer_count; i++) { + printf ("\t%s, %s\n", vk_props[i].layerName, vk_props[i].description); +/* res = init_global_extension_properties(layer_props); + if (res) return res; + info.instance_layer_properties.push_back(layer_props);*/ + } +} diff --git a/vkhelpers.h b/vkhelpers.h new file mode 100644 index 0000000..d26a688 --- /dev/null +++ b/vkhelpers.h @@ -0,0 +1,47 @@ +#ifndef VK_HELPERS_H +#define VK_HELPERS_H + +#include +#include +#include +#include +#include +#include + +#include + +#define FB_COLOR_FORMAT VK_FORMAT_B8G8R8A8_UNORM + +#define VK_CHECK_RESULT(f) \ +{ \ + VkResult res = (f); \ + if (res != VK_SUCCESS) \ + { \ + printf("Fatal : VkResult is %d in %s at line %d\n", res, __FILE__, __LINE__); \ + assert(res == VK_SUCCESS); \ + } \ +} + +VkPhysicalDevice vkh_find_phy (VkInstance inst, VkPhysicalDeviceType phyType); +VkFence vkh_fence_create (VkDevice dev); +VkSemaphore vkh_semaphore_create (VkDevice dev); +VkCommandPool vkh_cmd_pool_create (VkDevice dev, uint32_t qFamIndex, VkCommandPoolCreateFlags flags); +VkCommandBuffer vkh_cmd_buff_create (VkDevice dev, VkCommandPool cmdPool, VkCommandBufferLevel level); +void vkh_cmd_begin(VkCommandBuffer cmdBuff, VkCommandBufferUsageFlags flags); +void vkh_cmd_end(VkCommandBuffer cmdBuff); +void vkh_cmd_submit(VkQueue queue, VkCommandBuffer *pCmdBuff, VkFence fence); +void vkh_cmd_submit_with_semaphores(VkQueue queue, VkCommandBuffer *pCmdBuff, VkSemaphore waitSemaphore, + VkSemaphore signalSemaphore, VkFence fence); +void vkcrow_cmd_copy_submit(VkQueue queue, VkCommandBuffer *pCmdBuff, VkSemaphore* pWaitSemaphore, VkSemaphore* pSignalSemaphore); + +VkShaderModule vkh_load_module(VkDevice dev, const char* path); + +void set_image_layout(VkCommandBuffer cmdBuff, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout, + VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages); + +bool memory_type_from_properties(VkPhysicalDeviceMemoryProperties* memory_properties, uint32_t typeBits, 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 (); +#endif