/* * Assorted commonly used Vulkan helper functions * * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ #include "vulkantools.h" #ifdef __ANDROID__ #include "vulkanandroid.h" #endif namespace vkTools { VkBool32 checkGlobalExtensionPresent(const char* extensionName) { uint32_t extensionCount = 0; std::vector extensions; vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL); extensions.resize(extensionCount); vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions.data()); for (auto& ext : extensions) { if (!strcmp(extensionName, ext.extensionName)) { return true; } } return false; } VkBool32 checkDeviceExtensionPresent(VkPhysicalDevice physicalDevice, const char* extensionName) { uint32_t extensionCount = 0; std::vector extensions; vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, NULL); extensions.resize(extensionCount); vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &extensionCount, extensions.data()); for (auto& ext : extensions) { if (!strcmp(extensionName, ext.extensionName)) { return true; } } return false; } std::string errorString(VkResult errorCode) { switch (errorCode) { // todo : update to SDK 0.10.1 #define STR(r) case VK_ ##r: return #r STR(NOT_READY); STR(TIMEOUT); STR(EVENT_SET); STR(EVENT_RESET); STR(INCOMPLETE); STR(ERROR_OUT_OF_HOST_MEMORY); STR(ERROR_OUT_OF_DEVICE_MEMORY); STR(ERROR_INITIALIZATION_FAILED); STR(ERROR_DEVICE_LOST); STR(ERROR_MEMORY_MAP_FAILED); STR(ERROR_LAYER_NOT_PRESENT); STR(ERROR_EXTENSION_NOT_PRESENT); STR(ERROR_INCOMPATIBLE_DRIVER); #undef STR default: return "UNKNOWN_ERROR"; } } VkBool32 getSupportedDepthFormat(VkPhysicalDevice physicalDevice, VkFormat *depthFormat) { // Since all depth formats may be optional, we need to find a suitable depth format to use // Start with the highest precision packed format std::vector depthFormats = { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D16_UNORM, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SNORM }; for (auto& format : depthFormats) { VkFormatProperties formatProps; vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProps); // Format must support depth stencil attachment for optimal tiling if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { *depthFormat = format; return true; } } return false; } void insertImageMemoryBarrier( VkCommandBuffer cmdbuffer, VkImage image, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkImageSubresourceRange subresourceRange) { VkImageMemoryBarrier imageMemoryBarrier = vkTools::initializers::imageMemoryBarrier(); imageMemoryBarrier.srcAccessMask = srcAccessMask; imageMemoryBarrier.dstAccessMask = dstAccessMask; imageMemoryBarrier.oldLayout = oldImageLayout; imageMemoryBarrier.newLayout = newImageLayout; imageMemoryBarrier.image = image; imageMemoryBarrier.subresourceRange = subresourceRange; vkCmdPipelineBarrier( cmdbuffer, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); } // Create an image memory barrier for changing the layout of // an image and put it into an active command buffer // See chapter 11.4 "Image Layout" for details //todo : rename void setImageLayout(VkCommandBuffer cmdbuffer, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout) { // Create an image barrier object VkImageMemoryBarrier imageMemoryBarrier = vkTools::initializers::imageMemoryBarrier(); imageMemoryBarrier.oldLayout = oldImageLayout; imageMemoryBarrier.newLayout = newImageLayout; imageMemoryBarrier.image = image; imageMemoryBarrier.subresourceRange.aspectMask = aspectMask; imageMemoryBarrier.subresourceRange.baseMipLevel = 0; imageMemoryBarrier.subresourceRange.levelCount = 1; imageMemoryBarrier.subresourceRange.layerCount = 1; // Source layouts (old) // Undefined layout // Only allowed as initial layout! // Make sure any writes to the image have been finished if (oldImageLayout == VK_IMAGE_LAYOUT_UNDEFINED) { imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; } // Old layout is color attachment // Make sure any writes to the color buffer have been finished if (oldImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; } // Old layout is depth/stencil attachment // Make sure any writes to the depth/stencil buffer have been finished if (oldImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } // Old layout is transfer source // Make sure any reads from the image have been finished if (oldImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) { imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; } // Old layout is shader read (sampler, input attachment) // Make sure any shader reads from the image have been finished if (oldImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; } // Target layouts (new) // New layout is transfer destination (copy, blit) // Make sure any copyies to the image have been finished if (newImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; } // New layout is transfer source (copy, blit) // Make sure any reads from and writes to the image have been finished if (newImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) { imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VK_ACCESS_TRANSFER_READ_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; } // New layout is color attachment // Make sure any writes to the color buffer hav been finished if (newImageLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; } // New layout is depth attachment // Make sure any writes to depth/stencil buffer have been finished if (newImageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } // New layout is shader read (sampler, input attachment) // Make sure any writes to the image have been finished if (newImageLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; } // Put barrier on top of pipeline VkPipelineStageFlags srcStageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; VkPipelineStageFlags destStageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // Put barrier inside setup command buffer vkCmdPipelineBarrier( cmdbuffer, srcStageFlags, destStageFlags, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); } void exitFatal(std::string message, std::string caption) { MessageBox(NULL, message.c_str(), caption.c_str(), MB_OK | MB_ICONERROR); std::cerr << message << "\n"; return; } std::string readTextFile(const char *fileName) { std::string fileContent; std::ifstream fileStream(fileName, std::ios::in); if (!fileStream.is_open()) { printf("File %s not found\n", fileName); return ""; } std::string line = ""; while (!fileStream.eof()) { getline(fileStream, line); fileContent.append(line + "\n"); } fileStream.close(); return fileContent; } // Load a binary file into a buffer (e.g. SPIR-V) char *readBinaryFile(const char *filename, size_t *psize) { long int size; size_t retval; void *shader_code; 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; return (char*)shader_code; } VkShaderModule loadShader(const char *fileName, VkDevice device, VkShaderStageFlagBits stage) { size_t size = 0; const char *shaderCode = readBinaryFile(fileName, &size); assert(size > 0); VkShaderModule shaderModule; VkShaderModuleCreateInfo moduleCreateInfo; VkResult err; moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleCreateInfo.pNext = NULL; moduleCreateInfo.codeSize = size; moduleCreateInfo.pCode = (uint32_t*)shaderCode; moduleCreateInfo.flags = 0; err = vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule); assert(!err); return shaderModule; } VkShaderModule loadShaderGLSL(const char *fileName, VkDevice device, VkShaderStageFlagBits stage) { std::string shaderSrc = readTextFile(fileName); const char *shaderCode = shaderSrc.c_str(); size_t size = strlen(shaderCode); assert(size > 0); VkShaderModule shaderModule; VkShaderModuleCreateInfo moduleCreateInfo; VkResult err; moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleCreateInfo.pNext = NULL; moduleCreateInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; moduleCreateInfo.pCode = (uint32_t*)malloc(moduleCreateInfo.codeSize); moduleCreateInfo.flags = 0; // Magic SPV number ((uint32_t *)moduleCreateInfo.pCode)[0] = 0x07230203; ((uint32_t *)moduleCreateInfo.pCode)[1] = 0; ((uint32_t *)moduleCreateInfo.pCode)[2] = stage; memcpy(((uint32_t *)moduleCreateInfo.pCode + 3), shaderCode, size + 1); err = vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule); assert(!err); return shaderModule; } VkImageMemoryBarrier prePresentBarrier(VkImage presentImage) { VkImageMemoryBarrier imageMemoryBarrier = vkTools::initializers::imageMemoryBarrier(); imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.dstAccessMask = 0; imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; imageMemoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; imageMemoryBarrier.image = presentImage; return imageMemoryBarrier; } VkImageMemoryBarrier postPresentBarrier(VkImage presentImage) { VkImageMemoryBarrier imageMemoryBarrier = vkTools::initializers::imageMemoryBarrier(); imageMemoryBarrier.srcAccessMask = 0; imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; imageMemoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; imageMemoryBarrier.image = presentImage; return imageMemoryBarrier; } void destroyUniformData(VkDevice device, vkTools::UniformData *uniformData) { vkDestroyBuffer(device, uniformData->buffer, nullptr); vkFreeMemory(device, uniformData->memory, nullptr); } } VkMemoryAllocateInfo vkTools::initializers::memoryAllocateInfo() { VkMemoryAllocateInfo memAllocInfo = {}; memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.pNext = NULL; memAllocInfo.allocationSize = 0; memAllocInfo.memoryTypeIndex = 0; return memAllocInfo; } VkCommandBufferAllocateInfo vkTools::initializers::commandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount) { VkCommandBufferAllocateInfo commandBufferAllocateInfo = {}; commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; commandBufferAllocateInfo.commandPool = commandPool; commandBufferAllocateInfo.level = level; commandBufferAllocateInfo.commandBufferCount = bufferCount; return commandBufferAllocateInfo; } VkCommandPoolCreateInfo vkTools::initializers::commandPoolCreateInfo() { VkCommandPoolCreateInfo cmdPoolCreateInfo = {}; cmdPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; return cmdPoolCreateInfo; } VkCommandBufferBeginInfo vkTools::initializers::commandBufferBeginInfo() { VkCommandBufferBeginInfo cmdBufferBeginInfo = {}; cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cmdBufferBeginInfo.pNext = NULL; return cmdBufferBeginInfo; } VkCommandBufferInheritanceInfo vkTools::initializers::commandBufferInheritanceInfo() { VkCommandBufferInheritanceInfo cmdBufferInheritanceInfo = {}; cmdBufferInheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; return cmdBufferInheritanceInfo; } VkRenderPassBeginInfo vkTools::initializers::renderPassBeginInfo() { VkRenderPassBeginInfo renderPassBeginInfo = {}; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.pNext = NULL; return renderPassBeginInfo; } VkImageMemoryBarrier vkTools::initializers::imageMemoryBarrier() { VkImageMemoryBarrier imageMemoryBarrier = {}; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; imageMemoryBarrier.pNext = NULL; // Some default values imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; return imageMemoryBarrier; } VkBufferMemoryBarrier vkTools::initializers::bufferMemoryBarrier() { VkBufferMemoryBarrier bufferMemoryBarrier = {}; bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; bufferMemoryBarrier.pNext = NULL; return bufferMemoryBarrier; } VkMemoryBarrier vkTools::initializers::memoryBarrier() { VkMemoryBarrier memoryBarrier = {}; memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; memoryBarrier.pNext = NULL; return memoryBarrier; } VkImageCreateInfo vkTools::initializers::imageCreateInfo() { VkImageCreateInfo imageCreateInfo = {}; imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCreateInfo.pNext = NULL; return imageCreateInfo; } VkSamplerCreateInfo vkTools::initializers::samplerCreateInfo() { VkSamplerCreateInfo samplerCreateInfo = {}; samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; samplerCreateInfo.pNext = NULL; return samplerCreateInfo; } VkImageViewCreateInfo vkTools::initializers::imageViewCreateInfo() { VkImageViewCreateInfo imageViewCreateInfo = {}; imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; imageViewCreateInfo.pNext = NULL; return imageViewCreateInfo; } VkFramebufferCreateInfo vkTools::initializers::framebufferCreateInfo() { VkFramebufferCreateInfo framebufferCreateInfo = {}; framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferCreateInfo.pNext = NULL; return framebufferCreateInfo; } VkSemaphoreCreateInfo vkTools::initializers::semaphoreCreateInfo() { VkSemaphoreCreateInfo semaphoreCreateInfo = {}; semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; semaphoreCreateInfo.pNext = NULL; semaphoreCreateInfo.flags = 0; return semaphoreCreateInfo; } VkFenceCreateInfo vkTools::initializers::fenceCreateInfo(VkFenceCreateFlags flags) { VkFenceCreateInfo fenceCreateInfo = {}; fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceCreateInfo.flags = flags; return fenceCreateInfo; } VkSubmitInfo vkTools::initializers::submitInfo() { VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.pNext = NULL; return submitInfo; } VkViewport vkTools::initializers::viewport( float width, float height, float minDepth, float maxDepth) { VkViewport viewport = {}; viewport.width = width; viewport.height = height; viewport.minDepth = minDepth; viewport.maxDepth = maxDepth; return viewport; } VkRect2D vkTools::initializers::rect2D( int32_t width, int32_t height, int32_t offsetX, int32_t offsetY) { VkRect2D rect2D = {}; rect2D.extent.width = width; rect2D.extent.height = height; rect2D.offset.x = offsetX; rect2D.offset.y = offsetY; return rect2D; } VkBufferCreateInfo vkTools::initializers::bufferCreateInfo( VkBufferUsageFlags usage, VkDeviceSize size) { VkBufferCreateInfo bufCreateInfo = {}; bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufCreateInfo.pNext = NULL; bufCreateInfo.usage = usage; bufCreateInfo.size = size; bufCreateInfo.flags = 0; return bufCreateInfo; } VkDescriptorPoolCreateInfo vkTools::initializers::descriptorPoolCreateInfo( uint32_t poolSizeCount, VkDescriptorPoolSize* pPoolSizes, uint32_t maxSets) { VkDescriptorPoolCreateInfo descriptorPoolInfo = {}; descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptorPoolInfo.pNext = NULL; descriptorPoolInfo.poolSizeCount = poolSizeCount; descriptorPoolInfo.pPoolSizes = pPoolSizes; descriptorPoolInfo.maxSets = maxSets; return descriptorPoolInfo; } VkDescriptorPoolSize vkTools::initializers::descriptorPoolSize( VkDescriptorType type, uint32_t descriptorCount) { VkDescriptorPoolSize descriptorPoolSize = {}; descriptorPoolSize.type = type; descriptorPoolSize.descriptorCount = descriptorCount; return descriptorPoolSize; } VkDescriptorSetLayoutBinding vkTools::initializers::descriptorSetLayoutBinding( VkDescriptorType type, VkShaderStageFlags stageFlags, uint32_t binding) { VkDescriptorSetLayoutBinding setLayoutBinding = {}; setLayoutBinding.descriptorType = type; setLayoutBinding.stageFlags = stageFlags; setLayoutBinding.binding = binding; // Default value in all examples setLayoutBinding.descriptorCount = 1; return setLayoutBinding; } VkDescriptorSetLayoutCreateInfo vkTools::initializers::descriptorSetLayoutCreateInfo( const VkDescriptorSetLayoutBinding* pBindings, uint32_t bindingCount) { VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {}; descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; descriptorSetLayoutCreateInfo.pNext = NULL; descriptorSetLayoutCreateInfo.pBindings = pBindings; descriptorSetLayoutCreateInfo.bindingCount = bindingCount; return descriptorSetLayoutCreateInfo; } VkPipelineLayoutCreateInfo vkTools::initializers::pipelineLayoutCreateInfo( const VkDescriptorSetLayout* pSetLayouts, uint32_t setLayoutCount) { VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {}; pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutCreateInfo.pNext = NULL; pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount; pipelineLayoutCreateInfo.pSetLayouts = pSetLayouts; return pipelineLayoutCreateInfo; } VkDescriptorSetAllocateInfo vkTools::initializers::descriptorSetAllocateInfo( VkDescriptorPool descriptorPool, const VkDescriptorSetLayout* pSetLayouts, uint32_t descriptorSetCount) { VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {}; descriptorSetAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; descriptorSetAllocateInfo.pNext = NULL; descriptorSetAllocateInfo.descriptorPool = descriptorPool; descriptorSetAllocateInfo.pSetLayouts = pSetLayouts; descriptorSetAllocateInfo.descriptorSetCount = descriptorSetCount; return descriptorSetAllocateInfo; } VkDescriptorImageInfo vkTools::initializers::descriptorImageInfo(VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout) { VkDescriptorImageInfo descriptorImageInfo = {}; descriptorImageInfo.sampler = sampler; descriptorImageInfo.imageView = imageView; descriptorImageInfo.imageLayout = imageLayout; return descriptorImageInfo; } VkWriteDescriptorSet vkTools::initializers::writeDescriptorSet( VkDescriptorSet dstSet, VkDescriptorType type, uint32_t binding, VkDescriptorBufferInfo* bufferInfo) { VkWriteDescriptorSet writeDescriptorSet = {}; writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorSet.pNext = NULL; writeDescriptorSet.dstSet = dstSet; writeDescriptorSet.descriptorType = type; writeDescriptorSet.dstBinding = binding; writeDescriptorSet.pBufferInfo = bufferInfo; // Default value in all examples writeDescriptorSet.descriptorCount = 1; return writeDescriptorSet; } VkWriteDescriptorSet vkTools::initializers::writeDescriptorSet( VkDescriptorSet dstSet, VkDescriptorType type, uint32_t binding, VkDescriptorImageInfo * imageInfo) { VkWriteDescriptorSet writeDescriptorSet = {}; writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorSet.pNext = NULL; writeDescriptorSet.dstSet = dstSet; writeDescriptorSet.descriptorType = type; writeDescriptorSet.dstBinding = binding; writeDescriptorSet.pImageInfo = imageInfo; // Default value in all examples writeDescriptorSet.descriptorCount = 1; return writeDescriptorSet; } VkVertexInputBindingDescription vkTools::initializers::vertexInputBindingDescription( uint32_t binding, uint32_t stride, VkVertexInputRate inputRate) { VkVertexInputBindingDescription vInputBindDescription = {}; vInputBindDescription.binding = binding; vInputBindDescription.stride = stride; vInputBindDescription.inputRate = inputRate; return vInputBindDescription; } VkVertexInputAttributeDescription vkTools::initializers::vertexInputAttributeDescription( uint32_t binding, uint32_t location, VkFormat format, uint32_t offset) { VkVertexInputAttributeDescription vInputAttribDescription = {}; vInputAttribDescription.location = location; vInputAttribDescription.binding = binding; vInputAttribDescription.format = format; vInputAttribDescription.offset = offset; return vInputAttribDescription; } VkPipelineVertexInputStateCreateInfo vkTools::initializers::pipelineVertexInputStateCreateInfo() { VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {}; pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; pipelineVertexInputStateCreateInfo.pNext = NULL; return pipelineVertexInputStateCreateInfo; } VkPipelineInputAssemblyStateCreateInfo vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VkPrimitiveTopology topology, VkPipelineInputAssemblyStateCreateFlags flags, VkBool32 primitiveRestartEnable) { VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo = {}; pipelineInputAssemblyStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; pipelineInputAssemblyStateCreateInfo.topology = topology; pipelineInputAssemblyStateCreateInfo.flags = flags; pipelineInputAssemblyStateCreateInfo.primitiveRestartEnable = primitiveRestartEnable; return pipelineInputAssemblyStateCreateInfo; } VkPipelineRasterizationStateCreateInfo vkTools::initializers::pipelineRasterizationStateCreateInfo( VkPolygonMode polygonMode, VkCullModeFlags cullMode, VkFrontFace frontFace, VkPipelineRasterizationStateCreateFlags flags) { VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = {}; pipelineRasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; pipelineRasterizationStateCreateInfo.polygonMode = polygonMode; pipelineRasterizationStateCreateInfo.cullMode = cullMode; pipelineRasterizationStateCreateInfo.frontFace = frontFace; pipelineRasterizationStateCreateInfo.flags = flags; pipelineRasterizationStateCreateInfo.depthClampEnable = VK_TRUE; return pipelineRasterizationStateCreateInfo; } VkPipelineColorBlendAttachmentState vkTools::initializers::pipelineColorBlendAttachmentState( VkColorComponentFlags colorWriteMask, VkBool32 blendEnable) { VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = {}; pipelineColorBlendAttachmentState.colorWriteMask = colorWriteMask; pipelineColorBlendAttachmentState.blendEnable = blendEnable; return pipelineColorBlendAttachmentState; } VkPipelineColorBlendStateCreateInfo vkTools::initializers::pipelineColorBlendStateCreateInfo( uint32_t attachmentCount, const VkPipelineColorBlendAttachmentState * pAttachments) { VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {}; pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; pipelineColorBlendStateCreateInfo.pNext = NULL; pipelineColorBlendStateCreateInfo.attachmentCount = attachmentCount; pipelineColorBlendStateCreateInfo.pAttachments = pAttachments; return pipelineColorBlendStateCreateInfo; } VkPipelineDepthStencilStateCreateInfo vkTools::initializers::pipelineDepthStencilStateCreateInfo( VkBool32 depthTestEnable, VkBool32 depthWriteEnable, VkCompareOp depthCompareOp) { VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = {}; pipelineDepthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; pipelineDepthStencilStateCreateInfo.depthTestEnable = depthTestEnable; pipelineDepthStencilStateCreateInfo.depthWriteEnable = depthWriteEnable; pipelineDepthStencilStateCreateInfo.depthCompareOp = depthCompareOp; pipelineDepthStencilStateCreateInfo.front = pipelineDepthStencilStateCreateInfo.back; pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS; return pipelineDepthStencilStateCreateInfo; } VkPipelineViewportStateCreateInfo vkTools::initializers::pipelineViewportStateCreateInfo( uint32_t viewportCount, uint32_t scissorCount, VkPipelineViewportStateCreateFlags flags) { VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = {}; pipelineViewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; pipelineViewportStateCreateInfo.viewportCount = viewportCount; pipelineViewportStateCreateInfo.scissorCount = scissorCount; pipelineViewportStateCreateInfo.flags = flags; return pipelineViewportStateCreateInfo; } VkPipelineMultisampleStateCreateInfo vkTools::initializers::pipelineMultisampleStateCreateInfo( VkSampleCountFlagBits rasterizationSamples, VkPipelineMultisampleStateCreateFlags flags) { VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {}; pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; pipelineMultisampleStateCreateInfo.rasterizationSamples = rasterizationSamples; return pipelineMultisampleStateCreateInfo; } VkPipelineDynamicStateCreateInfo vkTools::initializers::pipelineDynamicStateCreateInfo( const VkDynamicState * pDynamicStates, uint32_t dynamicStateCount, VkPipelineDynamicStateCreateFlags flags) { VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {}; pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates; pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount; return pipelineDynamicStateCreateInfo; } VkPipelineTessellationStateCreateInfo vkTools::initializers::pipelineTessellationStateCreateInfo(uint32_t patchControlPoints) { VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo = {}; pipelineTessellationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; pipelineTessellationStateCreateInfo.patchControlPoints = patchControlPoints; return pipelineTessellationStateCreateInfo; } VkGraphicsPipelineCreateInfo vkTools::initializers::pipelineCreateInfo( VkPipelineLayout layout, VkRenderPass renderPass, VkPipelineCreateFlags flags) { VkGraphicsPipelineCreateInfo pipelineCreateInfo = {}; pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipelineCreateInfo.pNext = NULL; pipelineCreateInfo.layout = layout; pipelineCreateInfo.renderPass = renderPass; pipelineCreateInfo.flags = flags; return pipelineCreateInfo; } VkComputePipelineCreateInfo vkTools::initializers::computePipelineCreateInfo(VkPipelineLayout layout, VkPipelineCreateFlags flags) { VkComputePipelineCreateInfo computePipelineCreateInfo = {}; computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; computePipelineCreateInfo.layout = layout; computePipelineCreateInfo.flags = flags; return computePipelineCreateInfo; } VkPushConstantRange vkTools::initializers::pushConstantRange( VkShaderStageFlags stageFlags, uint32_t size, uint32_t offset) { VkPushConstantRange pushConstantRange = {}; pushConstantRange.stageFlags = stageFlags; pushConstantRange.offset = offset; pushConstantRange.size = size; return pushConstantRange; }