--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 3.9)
+
+PROJECT(vkh VERSION 0.1.0 DESCRIPTION "Vulkan helpers library")
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
+SET(CMAKE_CXX_FLAGS "-W -Wall")
+SET(CMAKE_EXE_LINKER_FLAGS "-lm")
+
+IF(NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE Release)
+ENDIF()
+MESSAGE(STATUS "${CMAKE_BUILD_TYPE} build.")
+
+FIND_PACKAGE(Vulkan REQUIRED)
+FIND_PACKAGE(GLFW3 REQUIRED)
+
+INCLUDE(GNUInstallDirs)
+
+FILE(GLOB VKH_SRC src/*.c)
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${VKH_SRC})
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
+ VERSION ${PROJECT_VERSION}
+ SOVERSION 1
+ PUBLIC_HEADER include/vkh.h
+)
+
+TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+)
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME}
+ ${Vulkan_LIBRARY}
+ ${GLFW3_LIBRARY}
+)
+
+CONFIGURE_FILE(vkh.pc.in vkh.pc @ONLY)
+
+INSTALL(FILES ${CMAKE_BINARY_DIR}/vkh.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
+INSTALL(TARGETS ${PROJECT_NAME}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
--- /dev/null
+# Locate the glfw3 library
+#
+# This module defines the following variables:
+#
+# GLFW3_LIBRARY the name of the library;
+# GLFW3_INCLUDE_DIR where to find glfw include files.
+# GLFW3_FOUND true if both the GLFW3_LIBRARY and GLFW3_INCLUDE_DIR have been found.
+#
+# To help locate the library and include file, you can define a
+# variable called GLFW3_ROOT which points to the root of the glfw library
+# installation.
+#
+# default search dirs
+#
+# Cmake file from: https://github.com/daw42/glslcookbook
+
+set( _glfw3_HEADER_SEARCH_DIRS
+"/usr/include"
+"/usr/local/include"
+"${CMAKE_SOURCE_DIR}/includes"
+"C:/Program Files (x86)/glfw/include" )
+set( _glfw3_LIB_SEARCH_DIRS
+"/usr/lib"
+"/usr/local/lib"
+"${CMAKE_SOURCE_DIR}/lib"
+"C:/Program Files (x86)/glfw/lib-msvc110" )
+
+# Check environment for root search directory
+set( _glfw3_ENV_ROOT $ENV{GLFW3_ROOT} )
+if( NOT GLFW3_ROOT AND _glfw3_ENV_ROOT )
+ set(GLFW3_ROOT ${_glfw3_ENV_ROOT} )
+endif()
+
+# Put user specified location at beginning of search
+if( GLFW3_ROOT )
+ list( INSERT _glfw3_HEADER_SEARCH_DIRS 0 "${GLFW3_ROOT}/include" )
+ list( INSERT _glfw3_LIB_SEARCH_DIRS 0 "${GLFW3_ROOT}/lib" )
+endif()
+
+# Search for the header
+FIND_PATH(GLFW3_INCLUDE_DIR "GLFW/glfw3.h"
+PATHS ${_glfw3_HEADER_SEARCH_DIRS} )
+
+# Search for the library
+FIND_LIBRARY(GLFW3_LIBRARY NAMES glfw3 glfw
+PATHS ${_glfw3_LIB_SEARCH_DIRS} )
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLFW3 DEFAULT_MSG
+GLFW3_LIBRARY GLFW3_INCLUDE_DIR)
--- /dev/null
+#ifndef VK_HELPERS_H
+#define VK_HELPERS_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <math.h>
+
+#include <vulkan/vulkan.h>
+
+#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); \
+ } \
+}
+
+typedef struct _vkh_device_t* VkhDevice;
+typedef struct _vkh_image_t* VkhImage;
+typedef struct _vkh_buffer_t* VkhBuffer;
+typedef struct _vkh_presenter_t* VkhPresenter;
+
+///////////////////////////////
+VkhImage vkh_image_create (VkhDevice pDev, VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling,
+ VkMemoryPropertyFlags memprops, VkImageUsageFlags usage);
+VkhImage vkh_image_ms_create (VkhDevice pDev, VkFormat format, VkSampleCountFlagBits num_samples, uint32_t width, uint32_t height,
+ VkMemoryPropertyFlags memprops, VkImageUsageFlags usage);
+VkhImage vkh_tex2d_array_create (VkhDevice pDev, VkFormat format, uint32_t width, uint32_t height, uint32_t layers,
+ VkMemoryPropertyFlags memprops, VkImageUsageFlags usage);
+void vkh_image_create_descriptor(VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags, VkFilter magFilter, VkFilter minFilter,
+ 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);
+void vkh_image_set_layout (VkCommandBuffer cmdBuff, VkhImage image, VkImageAspectFlags aspectMask,
+ VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
+void vkh_image_set_layout_subres(VkCommandBuffer cmdBuff, VkhImage image, VkImageSubresourceRange subresourceRange,
+ VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
+void vkh_image_destroy (VkhImage img);
+
+////////////////////////////////
+VkhBuffer vkh_buffer_create (VkhDevice pDev, VkBufferUsageFlags usage,
+ VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size);
+void vkh_buffer_destroy (VkhBuffer buff);
+VkResult vkh_buffer_map (VkhBuffer buff);
+void vkh_buffer_unmap (VkhBuffer buff);
+VkResult vkh_buffer_bind (VkhBuffer buff);
+///////////////////////////////
+
+VkFence vkh_fence_create (VkDevice dev);
+VkFence vkh_fence_create_signaled (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);
+
+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,
+ 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);
+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);
+#endif
--- /dev/null
+#include "vkh_buffer.h"
+#include "vkh_device.h"
+
+VkhBuffer vkh_buffer_create(VkhDevice pDev, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size){
+ VkhBuffer buff = (VkhBuffer)malloc(sizeof(vkh_buffer_t));
+ 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));
+ return buff;
+}
+
+void vkh_buffer_destroy(VkhBuffer buff){
+ if (buff->buffer)
+ vkDestroyBuffer(buff->pDev->vkDev, buff->buffer, NULL);
+ if (buff->memory)
+ vkFreeMemory(buff->pDev->vkDev, buff->memory, NULL);
+ free(buff);
+ buff = NULL;
+}
+
+
+VkResult vkh_buffer_map(VkhBuffer buff){
+ return vkMapMemory(buff->pDev->vkDev, buff->memory, 0, VK_WHOLE_SIZE, 0, &buff->mapped);
+}
+void vkh_buffer_unmap(VkhBuffer buff){
+ if (!buff->mapped)
+ return;
+ vkUnmapMemory(buff->pDev->vkDev, buff->memory);
+ buff->mapped = NULL;
+}
+
+VkResult vkh_buffer_bind(VkhBuffer buff)
+{
+ return vkBindBufferMemory(buff->pDev->vkDev, buff->buffer, buff->memory, 0);
+}
--- /dev/null
+#ifndef VKH_BUFFER_H
+#define VKH_BUFFER_H
+
+#include <vulkan/vulkan.h>
+#include "vkh.h"
+
+typedef struct _vkh_buffer_t {
+ VkhDevice pDev;
+ VkBuffer buffer;
+ VkDeviceMemory memory;
+ VkDescriptorBufferInfo descriptor;
+ VkDeviceSize size;
+ VkDeviceSize alignment;
+
+ VkBufferUsageFlags usageFlags;
+ VkMemoryPropertyFlags memoryPropertyFlags;
+
+ void* mapped;
+}vkh_buffer_t;
+#endif
--- /dev/null
+#include "vkh_device.h"
--- /dev/null
+#ifndef VKH_DEVICE_H
+#define VKH_DEVICE_H
+
+#include "vkh.h"
+
+typedef struct _vkh_device_t{
+ VkDevice vkDev;
+ VkPhysicalDeviceMemoryProperties phyMemProps;
+ VkRenderPass renderPass;
+}vkh_device_t;
+
+#endif
--- /dev/null
+#include "vkh_image.h"
+#include "vkh_device.h"
+
+VkhImage _vkh_image_create (VkhDevice 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){
+ VkhImage img = (VkhImage)calloc(1,sizeof(vkh_image_t));
+
+ img->pDev = pDev;
+ img->width = width;
+ img->height = height;
+ img->layout = VK_IMAGE_LAYOUT_UNDEFINED;
+ img->format = format;
+ img->layers = arrayLayers;
+ img->mipLevels = mipLevels;
+
+ VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+ .imageType = imageType,
+ .tiling = tiling,
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+ .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));
+
+ 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));
+ return img;
+}
+VkhImage vkh_tex2d_array_create (VkhDevice pDev,
+ VkFormat format, uint32_t width, uint32_t height, uint32_t layers,
+ VkMemoryPropertyFlags memprops, VkImageUsageFlags usage){
+ return _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage,
+ VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, 1, layers);
+}
+VkhImage vkh_image_create (VkhDevice pDev,
+ VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling,
+ VkMemoryPropertyFlags memprops,
+ VkImageUsageFlags usage)
+{
+ return _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage,
+ VK_SAMPLE_COUNT_1_BIT, tiling, 1, 1);
+}
+VkhImage vkh_image_ms_create(VkhDevice pDev,
+ VkFormat format, VkSampleCountFlagBits num_samples, uint32_t width, uint32_t height,
+ VkMemoryPropertyFlags memprops,
+ VkImageUsageFlags usage){
+ return _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage,
+ num_samples, VK_IMAGE_TILING_OPTIMAL, 1, 1);
+}
+void vkh_image_create_view (VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags){
+ if(img->view != VK_NULL_HANDLE)
+ vkDestroyImageView (img->pDev->vkDev,img->view,NULL);
+
+ VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+ .image = img->image,
+ .viewType = viewType,
+ .format = img->format,
+ .components = {VK_COMPONENT_SWIZZLE_R,VK_COMPONENT_SWIZZLE_G,VK_COMPONENT_SWIZZLE_B,VK_COMPONENT_SWIZZLE_A},
+ .subresourceRange = {aspectFlags,0,1,0,img->layers}};
+ VK_CHECK_RESULT(vkCreateImageView(img->pDev->vkDev, &viewInfo, NULL, &img->view));
+}
+void vkh_image_create_sampler (VkhImage img, VkFilter magFilter, VkFilter minFilter,
+ VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode){
+ if(img->sampler != VK_NULL_HANDLE)
+ vkDestroySampler (img->pDev->vkDev,img->sampler,NULL);
+ VkSamplerCreateInfo samplerCreateInfo = { .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+ .maxAnisotropy= 1.0,
+ .addressModeU = addressMode,
+ .addressModeV = addressMode,
+ .addressModeW = addressMode,
+ .magFilter = magFilter,
+ .minFilter = minFilter,
+ .mipmapMode = mipmapMode};
+ VK_CHECK_RESULT(vkCreateSampler(img->pDev->vkDev, &samplerCreateInfo, NULL, &img->sampler));
+}
+
+void vkh_image_create_descriptor(VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags, VkFilter magFilter,
+ VkFilter minFilter, VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode)
+{
+ vkh_image_create_view (img, viewType, aspectFlags);
+ vkh_image_create_sampler (img, magFilter, minFilter, mipmapMode, addressMode);
+}
+
+void vkh_image_set_layout(VkCommandBuffer cmdBuff, VkhImage image, VkImageAspectFlags aspectMask, VkImageLayout new_image_layout,
+ VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages) {
+ VkImageSubresourceRange subres = {aspectMask,0,1,0,1};
+ vkh_image_set_layout_subres(cmdBuff, image, subres, new_image_layout, src_stages, dest_stages);
+}
+
+void vkh_image_set_layout_subres(VkCommandBuffer cmdBuff, VkhImage image, VkImageSubresourceRange subresourceRange,
+ VkImageLayout new_image_layout,
+ VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages) {
+ VkImageMemoryBarrier image_memory_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ .oldLayout = image->layout,
+ .newLayout = new_image_layout,
+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
+ .image = image->image,
+ .subresourceRange = subresourceRange};
+
+ switch (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);
+ image->layout = new_image_layout;
+}
+
+void vkh_image_destroy(VkhImage img)
+{
+ if(img->view != VK_NULL_HANDLE)
+ vkDestroyImageView (img->pDev->vkDev,img->view,NULL);
+ if(img->sampler != VK_NULL_HANDLE)
+ vkDestroySampler (img->pDev->vkDev,img->sampler,NULL);
+
+ vkDestroyImage (img->pDev->vkDev, img->image, NULL);
+ vkFreeMemory (img->pDev->vkDev, img->memory, NULL);
+
+ free(img);
+ img = NULL;
+}
--- /dev/null
+#ifndef VKH_IMAGE_H
+#define VKH_IMAGE_H
+
+#include "vkh.h"
+
+typedef struct _vkh_image_t {
+ VkhDevice pDev;
+ VkFormat format;
+ uint32_t layers;
+ uint32_t mipLevels;
+ uint32_t width, height;
+ VkImage image;
+ VkDeviceMemory memory;
+ VkSampler sampler;
+ VkImageView view;
+ VkImageLayout layout; //current layout
+}vkh_image_t;
+#endif
--- /dev/null
+#include "vkh_presenter.h"
+
--- /dev/null
+#ifndef VKH_PRESENTER_H
+#define VKH_PRESENTER_H
+
+#include "vkh.h"
+
+typedef struct ImageBuffer_t {
+ VkImage image;
+ VkImageView view;
+}ImageBuffer;
+
+typedef struct _vkh_presenter_t {
+ VkQueue queue;
+ VkCommandPool cmdPool;
+ uint32_t qFam;
+ VkDevice dev;
+
+ //GLFWwindow* window;
+ VkSurfaceKHR surface;
+
+ VkSemaphore semaPresentEnd;
+ VkSemaphore semaDrawEnd;
+
+ VkFormat format;
+ VkColorSpaceKHR colorSpace;
+ VkPresentModeKHR presentMode;
+ uint32_t width;
+ uint32_t height;
+
+ uint32_t imgCount;
+ uint32_t currentScBufferIndex;
+
+ VkRenderPass renderPass;
+ VkSwapchainKHR swapChain;
+ ImageBuffer* ScBuffers;
+ VkCommandBuffer* cmdBuffs;
+ VkFramebuffer* frameBuffs;
+}vkh_presenter_t;
+
+#endif
--- /dev/null
+
+#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));
+
+ 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,
+ .pNext = NULL,
+ .flags = 0 };
+ VK_CHECK_RESULT(vkCreateFence(dev, &fenceInfo, NULL, &fence));
+ return fence;
+}
+VkFence vkh_fence_create_signaled (VkDevice dev) {
+ VkFence fence;
+ VkFenceCreateInfo fenceInfo = { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+ .pNext = NULL,
+ .flags = VK_FENCE_CREATE_SIGNALED_BIT };
+ 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) {
+ VkImageSubresourceRange subres = {aspectMask,0,1,0,1};
+ set_image_layout_subres(cmdBuff, image, subres, old_image_layout, new_image_layout, src_stages, 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) {
+ 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 = subresourceRange};
+
+ 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);*/
+ }
+}
--- /dev/null
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: @PROJECT_NAME@
+Description: @PROJECT_DESCRIPTION@
+Version: @PROJECT_VERSION@
+
+Requires:
+Libs: -L${libdir} -lvkh
+Cflags: -I${includedir}
+++ /dev/null
-#include "vkh_buffer.h"
-#include "vkh_device.h"
-
-VkhBuffer vkh_buffer_create(VkhDevice pDev, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size){
- VkhBuffer buff = (VkhBuffer)malloc(sizeof(vkh_buffer_t));
- 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));
- return buff;
-}
-
-void vkh_buffer_destroy(VkhBuffer buff){
- if (buff->buffer)
- vkDestroyBuffer(buff->pDev->vkDev, buff->buffer, NULL);
- if (buff->memory)
- vkFreeMemory(buff->pDev->vkDev, buff->memory, NULL);
- free(buff);
- buff = NULL;
-}
-
-
-VkResult vkh_buffer_map(VkhBuffer buff){
- return vkMapMemory(buff->pDev->vkDev, buff->memory, 0, VK_WHOLE_SIZE, 0, &buff->mapped);
-}
-void vkh_buffer_unmap(VkhBuffer buff){
- if (!buff->mapped)
- return;
- vkUnmapMemory(buff->pDev->vkDev, buff->memory);
- buff->mapped = NULL;
-}
-
-VkResult vkh_buffer_bind(VkhBuffer buff)
-{
- return vkBindBufferMemory(buff->pDev->vkDev, buff->buffer, buff->memory, 0);
-}
+++ /dev/null
-#ifndef VKH_BUFFER_H
-#define VKH_BUFFER_H
-
-#include <vulkan/vulkan.h>
-#include "vkhelpers.h"
-
-typedef struct _vkh_buffer_t {
- VkhDevice pDev;
- VkBuffer buffer;
- VkDeviceMemory memory;
- VkDescriptorBufferInfo descriptor;
- VkDeviceSize size;
- VkDeviceSize alignment;
-
- VkBufferUsageFlags usageFlags;
- VkMemoryPropertyFlags memoryPropertyFlags;
-
- void* mapped;
-}vkh_buffer_t;
-#endif
+++ /dev/null
-#include "vkh_device.h"
+++ /dev/null
-#ifndef VKH_DEVICE_H
-#define VKH_DEVICE_H
-
-#include "vkhelpers.h"
-
-typedef struct _vkh_device_t{
- VkDevice vkDev;
- VkPhysicalDeviceMemoryProperties phyMemProps;
- VkRenderPass renderPass;
-}vkh_device_t;
-
-#endif
+++ /dev/null
-#include "vkh_image.h"
-#include "vkh_device.h"
-
-VkhImage _vkh_image_create (VkhDevice 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){
- VkhImage img = (VkhImage)calloc(1,sizeof(vkh_image_t));
-
- img->pDev = pDev;
- img->width = width;
- img->height = height;
- img->layout = VK_IMAGE_LAYOUT_UNDEFINED;
- img->format = format;
- img->layers = arrayLayers;
- img->mipLevels = mipLevels;
-
- VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
- .imageType = imageType,
- .tiling = tiling,
- .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
- .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));
-
- 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));
- return img;
-}
-VkhImage vkh_tex2d_array_create (VkhDevice pDev,
- VkFormat format, uint32_t width, uint32_t height, uint32_t layers,
- VkMemoryPropertyFlags memprops, VkImageUsageFlags usage){
- return _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage,
- VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, 1, layers);
-}
-VkhImage vkh_image_create (VkhDevice pDev,
- VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling,
- VkMemoryPropertyFlags memprops,
- VkImageUsageFlags usage)
-{
- return _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage,
- VK_SAMPLE_COUNT_1_BIT, tiling, 1, 1);
-}
-VkhImage vkh_image_ms_create(VkhDevice pDev,
- VkFormat format, VkSampleCountFlagBits num_samples, uint32_t width, uint32_t height,
- VkMemoryPropertyFlags memprops,
- VkImageUsageFlags usage){
- return _vkh_image_create (pDev, VK_IMAGE_TYPE_2D, format, width, height, memprops,usage,
- num_samples, VK_IMAGE_TILING_OPTIMAL, 1, 1);
-}
-void vkh_image_create_view (VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags){
- if(img->view != VK_NULL_HANDLE)
- vkDestroyImageView (img->pDev->vkDev,img->view,NULL);
-
- VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .image = img->image,
- .viewType = viewType,
- .format = img->format,
- .components = {VK_COMPONENT_SWIZZLE_R,VK_COMPONENT_SWIZZLE_G,VK_COMPONENT_SWIZZLE_B,VK_COMPONENT_SWIZZLE_A},
- .subresourceRange = {aspectFlags,0,1,0,img->layers}};
- VK_CHECK_RESULT(vkCreateImageView(img->pDev->vkDev, &viewInfo, NULL, &img->view));
-}
-void vkh_image_create_sampler (VkhImage img, VkFilter magFilter, VkFilter minFilter,
- VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode){
- if(img->sampler != VK_NULL_HANDLE)
- vkDestroySampler (img->pDev->vkDev,img->sampler,NULL);
- VkSamplerCreateInfo samplerCreateInfo = { .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
- .maxAnisotropy= 1.0,
- .addressModeU = addressMode,
- .addressModeV = addressMode,
- .addressModeW = addressMode,
- .magFilter = magFilter,
- .minFilter = minFilter,
- .mipmapMode = mipmapMode};
- VK_CHECK_RESULT(vkCreateSampler(img->pDev->vkDev, &samplerCreateInfo, NULL, &img->sampler));
-}
-
-void vkh_image_create_descriptor(VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags, VkFilter magFilter,
- VkFilter minFilter, VkSamplerMipmapMode mipmapMode, VkSamplerAddressMode addressMode)
-{
- vkh_image_create_view (img, viewType, aspectFlags);
- vkh_image_create_sampler (img, magFilter, minFilter, mipmapMode, addressMode);
-}
-
-void vkh_image_set_layout(VkCommandBuffer cmdBuff, VkhImage image, VkImageAspectFlags aspectMask, VkImageLayout new_image_layout,
- VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages) {
- VkImageSubresourceRange subres = {aspectMask,0,1,0,1};
- vkh_image_set_layout_subres(cmdBuff, image, subres, new_image_layout, src_stages, dest_stages);
-}
-
-void vkh_image_set_layout_subres(VkCommandBuffer cmdBuff, VkhImage image, VkImageSubresourceRange subresourceRange,
- VkImageLayout new_image_layout,
- VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages) {
- VkImageMemoryBarrier image_memory_barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- .oldLayout = image->layout,
- .newLayout = new_image_layout,
- .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = image->image,
- .subresourceRange = subresourceRange};
-
- switch (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);
- image->layout = new_image_layout;
-}
-
-void vkh_image_destroy(VkhImage img)
-{
- if(img->view != VK_NULL_HANDLE)
- vkDestroyImageView (img->pDev->vkDev,img->view,NULL);
- if(img->sampler != VK_NULL_HANDLE)
- vkDestroySampler (img->pDev->vkDev,img->sampler,NULL);
-
- vkDestroyImage (img->pDev->vkDev, img->image, NULL);
- vkFreeMemory (img->pDev->vkDev, img->memory, NULL);
-
- free(img);
- img = NULL;
-}
+++ /dev/null
-#ifndef VKH_IMAGE_H
-#define VKH_IMAGE_H
-
-#include "vkhelpers.h"
-
-typedef struct _vkh_image_t {
- VkhDevice pDev;
- VkFormat format;
- uint32_t layers;
- uint32_t mipLevels;
- uint32_t width, height;
- VkImage image;
- VkDeviceMemory memory;
- VkSampler sampler;
- VkImageView view;
- VkImageLayout layout; //current layout
-}vkh_image_t;
-#endif
+++ /dev/null
-#include "vkh_presenter.h"
-
+++ /dev/null
-#ifndef VKH_PRESENTER_H
-#define VKH_PRESENTER_H
-
-#include "vkhelpers.h"
-
-
-
-#endif
+++ /dev/null
-
-#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<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,
- .pNext = NULL,
- .flags = 0 };
- VK_CHECK_RESULT(vkCreateFence(dev, &fenceInfo, NULL, &fence));
- return fence;
-}
-VkFence vkh_fence_create_signaled (VkDevice dev) {
- VkFence fence;
- VkFenceCreateInfo fenceInfo = { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
- .pNext = NULL,
- .flags = VK_FENCE_CREATE_SIGNALED_BIT };
- 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) {
- VkImageSubresourceRange subres = {aspectMask,0,1,0,1};
- set_image_layout_subres(cmdBuff, image, subres, old_image_layout, new_image_layout, src_stages, 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) {
- 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 = subresourceRange};
-
- 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);*/
- }
-}
+++ /dev/null
-#ifndef VK_HELPERS_H
-#define VK_HELPERS_H
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <math.h>
-
-#include <vulkan/vulkan.h>
-
-#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); \
- } \
-}
-
-typedef struct _vkh_device_t* VkhDevice;
-typedef struct _vkh_image_t* VkhImage;
-typedef struct _vkh_buffer_t* VkhBuffer;
-
-///////////////////////////////
-VkhImage vkh_image_create (VkhDevice pDev, VkFormat format, uint32_t width, uint32_t height, VkImageTiling tiling,
- VkMemoryPropertyFlags memprops, VkImageUsageFlags usage);
-VkhImage vkh_image_ms_create (VkhDevice pDev, VkFormat format, VkSampleCountFlagBits num_samples, uint32_t width, uint32_t height,
- VkMemoryPropertyFlags memprops, VkImageUsageFlags usage);
-VkhImage vkh_tex2d_array_create (VkhDevice pDev, VkFormat format, uint32_t width, uint32_t height, uint32_t layers,
- VkMemoryPropertyFlags memprops, VkImageUsageFlags usage);
-void vkh_image_create_descriptor(VkhImage img, VkImageViewType viewType, VkImageAspectFlags aspectFlags, VkFilter magFilter, VkFilter minFilter,
- 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);
-void vkh_image_set_layout (VkCommandBuffer cmdBuff, VkhImage image, VkImageAspectFlags aspectMask,
- VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
-void vkh_image_set_layout_subres(VkCommandBuffer cmdBuff, VkhImage image, VkImageSubresourceRange subresourceRange,
- VkImageLayout new_image_layout, VkPipelineStageFlags src_stages, VkPipelineStageFlags dest_stages);
-void vkh_image_destroy (VkhImage img);
-
-////////////////////////////////
-VkhBuffer vkh_buffer_create (VkhDevice pDev, VkBufferUsageFlags usage,
- VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize size);
-void vkh_buffer_destroy (VkhBuffer buff);
-VkResult vkh_buffer_map (VkhBuffer buff);
-void vkh_buffer_unmap (VkhBuffer buff);
-VkResult vkh_buffer_bind (VkhBuffer buff);
-///////////////////////////////
-
-VkFence vkh_fence_create (VkDevice dev);
-VkFence vkh_fence_create_signaled (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);
-
-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,
- 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);
-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);
-#endif