diff --git a/Makefile b/Makefile index 1b8eb5601..8af4f4753 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ build_shaders: $(SCMP) -V shaders/glsl/computeheadless.comp -o shaders/glsl/computeheadless.comp.spv format: - $(CF) -i -style=mozilla src/*.cpp src/*.h src/*.hpp + $(CF) -i -style="{BasedOnStyle: mozilla, IndentWidth: 4}" src/*.cpp src/*.h src/*.hpp clean: rm ./bin/main.exe; diff --git a/src/VulkanInitializers.hpp b/src/VulkanInitializers.hpp index d9a056cc6..81a2621b5 100644 --- a/src/VulkanInitializers.hpp +++ b/src/VulkanInitializers.hpp @@ -20,17 +20,17 @@ namespace initializers { inline VkMemoryAllocateInfo memoryAllocateInfo() { - VkMemoryAllocateInfo memAllocInfo{}; - memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - return memAllocInfo; + VkMemoryAllocateInfo memAllocInfo{}; + memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + return memAllocInfo; } inline VkMappedMemoryRange mappedMemoryRange() { - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - return mappedMemoryRange; + VkMappedMemoryRange mappedMemoryRange{}; + mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + return mappedMemoryRange; } inline VkCommandBufferAllocateInfo @@ -38,54 +38,54 @@ 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; + VkCommandBufferAllocateInfo commandBufferAllocateInfo{}; + commandBufferAllocateInfo.sType = + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocateInfo.commandPool = commandPool; + commandBufferAllocateInfo.level = level; + commandBufferAllocateInfo.commandBufferCount = bufferCount; + return commandBufferAllocateInfo; } inline VkCommandPoolCreateInfo commandPoolCreateInfo() { - VkCommandPoolCreateInfo cmdPoolCreateInfo{}; - cmdPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - return cmdPoolCreateInfo; + VkCommandPoolCreateInfo cmdPoolCreateInfo{}; + cmdPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + return cmdPoolCreateInfo; } inline VkCommandBufferBeginInfo commandBufferBeginInfo() { - VkCommandBufferBeginInfo cmdBufferBeginInfo{}; - cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - return cmdBufferBeginInfo; + VkCommandBufferBeginInfo cmdBufferBeginInfo{}; + cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + return cmdBufferBeginInfo; } inline VkCommandBufferInheritanceInfo commandBufferInheritanceInfo() { - VkCommandBufferInheritanceInfo cmdBufferInheritanceInfo{}; - cmdBufferInheritanceInfo.sType = - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; - return cmdBufferInheritanceInfo; + VkCommandBufferInheritanceInfo cmdBufferInheritanceInfo{}; + cmdBufferInheritanceInfo.sType = + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; + return cmdBufferInheritanceInfo; } inline VkRenderPassBeginInfo renderPassBeginInfo() { - VkRenderPassBeginInfo renderPassBeginInfo{}; - renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - return renderPassBeginInfo; + VkRenderPassBeginInfo renderPassBeginInfo{}; + renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + return renderPassBeginInfo; } inline VkRenderPassCreateInfo renderPassCreateInfo() { - VkRenderPassCreateInfo renderPassCreateInfo{}; - renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - return renderPassCreateInfo; + VkRenderPassCreateInfo renderPassCreateInfo{}; + renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + return renderPassCreateInfo; } /** @brief Initialize an image memory barrier with no image transfer ownership @@ -93,11 +93,11 @@ renderPassCreateInfo() inline VkImageMemoryBarrier imageMemoryBarrier() { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - return imageMemoryBarrier; + VkImageMemoryBarrier imageMemoryBarrier{}; + imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + return imageMemoryBarrier; } /** @brief Initialize a buffer memory barrier with no image transfer ownership @@ -105,125 +105,125 @@ imageMemoryBarrier() inline VkBufferMemoryBarrier bufferMemoryBarrier() { - VkBufferMemoryBarrier bufferMemoryBarrier{}; - bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; - bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - return bufferMemoryBarrier; + VkBufferMemoryBarrier bufferMemoryBarrier{}; + bufferMemoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + return bufferMemoryBarrier; } inline VkMemoryBarrier memoryBarrier() { - VkMemoryBarrier memoryBarrier{}; - memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; - return memoryBarrier; + VkMemoryBarrier memoryBarrier{}; + memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + return memoryBarrier; } inline VkImageCreateInfo imageCreateInfo() { - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - return imageCreateInfo; + VkImageCreateInfo imageCreateInfo{}; + imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + return imageCreateInfo; } inline VkSamplerCreateInfo samplerCreateInfo() { - VkSamplerCreateInfo samplerCreateInfo{}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.maxAnisotropy = 1.0f; - return samplerCreateInfo; + VkSamplerCreateInfo samplerCreateInfo{}; + samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerCreateInfo.maxAnisotropy = 1.0f; + return samplerCreateInfo; } inline VkImageViewCreateInfo imageViewCreateInfo() { - VkImageViewCreateInfo imageViewCreateInfo{}; - imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - return imageViewCreateInfo; + VkImageViewCreateInfo imageViewCreateInfo{}; + imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + return imageViewCreateInfo; } inline VkFramebufferCreateInfo framebufferCreateInfo() { - VkFramebufferCreateInfo framebufferCreateInfo{}; - framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - return framebufferCreateInfo; + VkFramebufferCreateInfo framebufferCreateInfo{}; + framebufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + return framebufferCreateInfo; } inline VkSemaphoreCreateInfo semaphoreCreateInfo() { - VkSemaphoreCreateInfo semaphoreCreateInfo{}; - semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - return semaphoreCreateInfo; + VkSemaphoreCreateInfo semaphoreCreateInfo{}; + semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + return semaphoreCreateInfo; } inline VkFenceCreateInfo fenceCreateInfo(VkFenceCreateFlags flags = 0) { - VkFenceCreateInfo fenceCreateInfo{}; - fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceCreateInfo.flags = flags; - return fenceCreateInfo; + VkFenceCreateInfo fenceCreateInfo{}; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.flags = flags; + return fenceCreateInfo; } inline VkEventCreateInfo eventCreateInfo() { - VkEventCreateInfo eventCreateInfo{}; - eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; - return eventCreateInfo; + VkEventCreateInfo eventCreateInfo{}; + eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; + return eventCreateInfo; } inline VkSubmitInfo submitInfo() { - VkSubmitInfo submitInfo{}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - return submitInfo; + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + return submitInfo; } inline VkViewport 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; + VkViewport viewport{}; + viewport.width = width; + viewport.height = height; + viewport.minDepth = minDepth; + viewport.maxDepth = maxDepth; + return viewport; } inline VkRect2D 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; + VkRect2D rect2D{}; + rect2D.extent.width = width; + rect2D.extent.height = height; + rect2D.offset.x = offsetX; + rect2D.offset.y = offsetY; + return rect2D; } inline VkBufferCreateInfo bufferCreateInfo() { - VkBufferCreateInfo bufCreateInfo{}; - bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - return bufCreateInfo; + VkBufferCreateInfo bufCreateInfo{}; + bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + return bufCreateInfo; } inline VkBufferCreateInfo bufferCreateInfo(VkBufferUsageFlags usage, VkDeviceSize size) { - VkBufferCreateInfo bufCreateInfo{}; - bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufCreateInfo.usage = usage; - bufCreateInfo.size = size; - return bufCreateInfo; + VkBufferCreateInfo bufCreateInfo{}; + bufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufCreateInfo.usage = usage; + bufCreateInfo.size = size; + return bufCreateInfo; } inline VkDescriptorPoolCreateInfo @@ -231,33 +231,33 @@ descriptorPoolCreateInfo(uint32_t poolSizeCount, VkDescriptorPoolSize* pPoolSizes, uint32_t maxSets) { - VkDescriptorPoolCreateInfo descriptorPoolInfo{}; - descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descriptorPoolInfo.poolSizeCount = poolSizeCount; - descriptorPoolInfo.pPoolSizes = pPoolSizes; - descriptorPoolInfo.maxSets = maxSets; - return descriptorPoolInfo; + VkDescriptorPoolCreateInfo descriptorPoolInfo{}; + descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolInfo.poolSizeCount = poolSizeCount; + descriptorPoolInfo.pPoolSizes = pPoolSizes; + descriptorPoolInfo.maxSets = maxSets; + return descriptorPoolInfo; } inline VkDescriptorPoolCreateInfo descriptorPoolCreateInfo(const std::vector& poolSizes, uint32_t maxSets) { - VkDescriptorPoolCreateInfo descriptorPoolInfo{}; - descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descriptorPoolInfo.poolSizeCount = static_cast(poolSizes.size()); - descriptorPoolInfo.pPoolSizes = poolSizes.data(); - descriptorPoolInfo.maxSets = maxSets; - return descriptorPoolInfo; + VkDescriptorPoolCreateInfo descriptorPoolInfo{}; + descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descriptorPoolInfo.poolSizeCount = static_cast(poolSizes.size()); + descriptorPoolInfo.pPoolSizes = poolSizes.data(); + descriptorPoolInfo.maxSets = maxSets; + return descriptorPoolInfo; } inline VkDescriptorPoolSize descriptorPoolSize(VkDescriptorType type, uint32_t descriptorCount) { - VkDescriptorPoolSize descriptorPoolSize{}; - descriptorPoolSize.type = type; - descriptorPoolSize.descriptorCount = descriptorCount; - return descriptorPoolSize; + VkDescriptorPoolSize descriptorPoolSize{}; + descriptorPoolSize.type = type; + descriptorPoolSize.descriptorCount = descriptorCount; + return descriptorPoolSize; } inline VkDescriptorSetLayoutBinding @@ -266,59 +266,59 @@ descriptorSetLayoutBinding(VkDescriptorType type, uint32_t binding, uint32_t descriptorCount = 1) { - VkDescriptorSetLayoutBinding setLayoutBinding{}; - setLayoutBinding.descriptorType = type; - setLayoutBinding.stageFlags = stageFlags; - setLayoutBinding.binding = binding; - setLayoutBinding.descriptorCount = descriptorCount; - return setLayoutBinding; + VkDescriptorSetLayoutBinding setLayoutBinding{}; + setLayoutBinding.descriptorType = type; + setLayoutBinding.stageFlags = stageFlags; + setLayoutBinding.binding = binding; + setLayoutBinding.descriptorCount = descriptorCount; + return setLayoutBinding; } inline VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo(const VkDescriptorSetLayoutBinding* pBindings, uint32_t bindingCount) { - VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{}; - descriptorSetLayoutCreateInfo.sType = - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptorSetLayoutCreateInfo.pBindings = pBindings; - descriptorSetLayoutCreateInfo.bindingCount = bindingCount; - return descriptorSetLayoutCreateInfo; + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{}; + descriptorSetLayoutCreateInfo.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptorSetLayoutCreateInfo.pBindings = pBindings; + descriptorSetLayoutCreateInfo.bindingCount = bindingCount; + return descriptorSetLayoutCreateInfo; } inline VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo( const std::vector& bindings) { - VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{}; - descriptorSetLayoutCreateInfo.sType = - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptorSetLayoutCreateInfo.pBindings = bindings.data(); - descriptorSetLayoutCreateInfo.bindingCount = - static_cast(bindings.size()); - return descriptorSetLayoutCreateInfo; + VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{}; + descriptorSetLayoutCreateInfo.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + descriptorSetLayoutCreateInfo.pBindings = bindings.data(); + descriptorSetLayoutCreateInfo.bindingCount = + static_cast(bindings.size()); + return descriptorSetLayoutCreateInfo; } inline VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo(const VkDescriptorSetLayout* pSetLayouts, uint32_t setLayoutCount = 1) { - VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{}; - pipelineLayoutCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount; - pipelineLayoutCreateInfo.pSetLayouts = pSetLayouts; - return pipelineLayoutCreateInfo; + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{}; + pipelineLayoutCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount; + pipelineLayoutCreateInfo.pSetLayouts = pSetLayouts; + return pipelineLayoutCreateInfo; } inline VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo(uint32_t setLayoutCount = 1) { - VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{}; - pipelineLayoutCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount; - return pipelineLayoutCreateInfo; + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{}; + pipelineLayoutCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount; + return pipelineLayoutCreateInfo; } inline VkDescriptorSetAllocateInfo @@ -326,13 +326,13 @@ descriptorSetAllocateInfo(VkDescriptorPool descriptorPool, const VkDescriptorSetLayout* pSetLayouts, uint32_t descriptorSetCount) { - VkDescriptorSetAllocateInfo descriptorSetAllocateInfo{}; - descriptorSetAllocateInfo.sType = - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - descriptorSetAllocateInfo.descriptorPool = descriptorPool; - descriptorSetAllocateInfo.pSetLayouts = pSetLayouts; - descriptorSetAllocateInfo.descriptorSetCount = descriptorSetCount; - return descriptorSetAllocateInfo; + VkDescriptorSetAllocateInfo descriptorSetAllocateInfo{}; + descriptorSetAllocateInfo.sType = + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + descriptorSetAllocateInfo.descriptorPool = descriptorPool; + descriptorSetAllocateInfo.pSetLayouts = pSetLayouts; + descriptorSetAllocateInfo.descriptorSetCount = descriptorSetCount; + return descriptorSetAllocateInfo; } inline VkDescriptorImageInfo @@ -340,11 +340,11 @@ descriptorImageInfo(VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout) { - VkDescriptorImageInfo descriptorImageInfo{}; - descriptorImageInfo.sampler = sampler; - descriptorImageInfo.imageView = imageView; - descriptorImageInfo.imageLayout = imageLayout; - return descriptorImageInfo; + VkDescriptorImageInfo descriptorImageInfo{}; + descriptorImageInfo.sampler = sampler; + descriptorImageInfo.imageView = imageView; + descriptorImageInfo.imageLayout = imageLayout; + return descriptorImageInfo; } inline VkWriteDescriptorSet @@ -354,14 +354,14 @@ writeDescriptorSet(VkDescriptorSet dstSet, VkDescriptorBufferInfo* bufferInfo, uint32_t descriptorCount = 1) { - VkWriteDescriptorSet writeDescriptorSet{}; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = dstSet; - writeDescriptorSet.descriptorType = type; - writeDescriptorSet.dstBinding = binding; - writeDescriptorSet.pBufferInfo = bufferInfo; - writeDescriptorSet.descriptorCount = descriptorCount; - return writeDescriptorSet; + VkWriteDescriptorSet writeDescriptorSet{}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = dstSet; + writeDescriptorSet.descriptorType = type; + writeDescriptorSet.dstBinding = binding; + writeDescriptorSet.pBufferInfo = bufferInfo; + writeDescriptorSet.descriptorCount = descriptorCount; + return writeDescriptorSet; } inline VkWriteDescriptorSet @@ -371,14 +371,14 @@ writeDescriptorSet(VkDescriptorSet dstSet, VkDescriptorImageInfo* imageInfo, uint32_t descriptorCount = 1) { - VkWriteDescriptorSet writeDescriptorSet{}; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = dstSet; - writeDescriptorSet.descriptorType = type; - writeDescriptorSet.dstBinding = binding; - writeDescriptorSet.pImageInfo = imageInfo; - writeDescriptorSet.descriptorCount = descriptorCount; - return writeDescriptorSet; + VkWriteDescriptorSet writeDescriptorSet{}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = dstSet; + writeDescriptorSet.descriptorType = type; + writeDescriptorSet.dstBinding = binding; + writeDescriptorSet.pImageInfo = imageInfo; + writeDescriptorSet.descriptorCount = descriptorCount; + return writeDescriptorSet; } inline VkVertexInputBindingDescription @@ -386,11 +386,11 @@ vertexInputBindingDescription(uint32_t binding, uint32_t stride, VkVertexInputRate inputRate) { - VkVertexInputBindingDescription vInputBindDescription{}; - vInputBindDescription.binding = binding; - vInputBindDescription.stride = stride; - vInputBindDescription.inputRate = inputRate; - return vInputBindDescription; + VkVertexInputBindingDescription vInputBindDescription{}; + vInputBindDescription.binding = binding; + vInputBindDescription.stride = stride; + vInputBindDescription.inputRate = inputRate; + return vInputBindDescription; } inline VkVertexInputAttributeDescription @@ -399,21 +399,21 @@ vertexInputAttributeDescription(uint32_t binding, VkFormat format, uint32_t offset) { - VkVertexInputAttributeDescription vInputAttribDescription{}; - vInputAttribDescription.location = location; - vInputAttribDescription.binding = binding; - vInputAttribDescription.format = format; - vInputAttribDescription.offset = offset; - return vInputAttribDescription; + VkVertexInputAttributeDescription vInputAttribDescription{}; + vInputAttribDescription.location = location; + vInputAttribDescription.binding = binding; + vInputAttribDescription.format = format; + vInputAttribDescription.offset = offset; + return vInputAttribDescription; } inline VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo() { - VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo{}; - pipelineVertexInputStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - return pipelineVertexInputStateCreateInfo; + VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo{}; + pipelineVertexInputStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + return pipelineVertexInputStateCreateInfo; } inline VkPipelineVertexInputStateCreateInfo @@ -422,18 +422,18 @@ pipelineVertexInputStateCreateInfo( const std::vector& vertexAttributeDescriptions) { - VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo{}; - pipelineVertexInputStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - pipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = - static_cast(vertexBindingDescriptions.size()); - pipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = - vertexBindingDescriptions.data(); - pipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = - static_cast(vertexAttributeDescriptions.size()); - pipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = - vertexAttributeDescriptions.data(); - return pipelineVertexInputStateCreateInfo; + VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo{}; + pipelineVertexInputStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + pipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = + static_cast(vertexBindingDescriptions.size()); + pipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = + vertexBindingDescriptions.data(); + pipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = + static_cast(vertexAttributeDescriptions.size()); + pipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = + vertexAttributeDescriptions.data(); + return pipelineVertexInputStateCreateInfo; } inline VkPipelineInputAssemblyStateCreateInfo @@ -442,14 +442,15 @@ pipelineInputAssemblyStateCreateInfo( 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; + VkPipelineInputAssemblyStateCreateInfo + pipelineInputAssemblyStateCreateInfo{}; + pipelineInputAssemblyStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + pipelineInputAssemblyStateCreateInfo.topology = topology; + pipelineInputAssemblyStateCreateInfo.flags = flags; + pipelineInputAssemblyStateCreateInfo.primitiveRestartEnable = + primitiveRestartEnable; + return pipelineInputAssemblyStateCreateInfo; } inline VkPipelineRasterizationStateCreateInfo @@ -459,26 +460,27 @@ pipelineRasterizationStateCreateInfo( VkFrontFace frontFace, VkPipelineRasterizationStateCreateFlags flags = 0) { - 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_FALSE; - pipelineRasterizationStateCreateInfo.lineWidth = 1.0f; - return pipelineRasterizationStateCreateInfo; + 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_FALSE; + pipelineRasterizationStateCreateInfo.lineWidth = 1.0f; + return pipelineRasterizationStateCreateInfo; } inline VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState(VkColorComponentFlags colorWriteMask, VkBool32 blendEnable) { - VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState{}; - pipelineColorBlendAttachmentState.colorWriteMask = colorWriteMask; - pipelineColorBlendAttachmentState.blendEnable = blendEnable; - return pipelineColorBlendAttachmentState; + VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState{}; + pipelineColorBlendAttachmentState.colorWriteMask = colorWriteMask; + pipelineColorBlendAttachmentState.blendEnable = blendEnable; + return pipelineColorBlendAttachmentState; } inline VkPipelineColorBlendStateCreateInfo @@ -486,12 +488,12 @@ pipelineColorBlendStateCreateInfo( uint32_t attachmentCount, const VkPipelineColorBlendAttachmentState* pAttachments) { - VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo{}; - pipelineColorBlendStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - pipelineColorBlendStateCreateInfo.attachmentCount = attachmentCount; - pipelineColorBlendStateCreateInfo.pAttachments = pAttachments; - return pipelineColorBlendStateCreateInfo; + VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo{}; + pipelineColorBlendStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + pipelineColorBlendStateCreateInfo.attachmentCount = attachmentCount; + pipelineColorBlendStateCreateInfo.pAttachments = pAttachments; + return pipelineColorBlendStateCreateInfo; } inline VkPipelineDepthStencilStateCreateInfo @@ -499,14 +501,14 @@ 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.back.compareOp = VK_COMPARE_OP_ALWAYS; - return pipelineDepthStencilStateCreateInfo; + VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo{}; + pipelineDepthStencilStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + pipelineDepthStencilStateCreateInfo.depthTestEnable = depthTestEnable; + pipelineDepthStencilStateCreateInfo.depthWriteEnable = depthWriteEnable; + pipelineDepthStencilStateCreateInfo.depthCompareOp = depthCompareOp; + pipelineDepthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS; + return pipelineDepthStencilStateCreateInfo; } inline VkPipelineViewportStateCreateInfo @@ -514,13 +516,13 @@ pipelineViewportStateCreateInfo(uint32_t viewportCount, uint32_t scissorCount, VkPipelineViewportStateCreateFlags flags = 0) { - VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo{}; - pipelineViewportStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - pipelineViewportStateCreateInfo.viewportCount = viewportCount; - pipelineViewportStateCreateInfo.scissorCount = scissorCount; - pipelineViewportStateCreateInfo.flags = flags; - return pipelineViewportStateCreateInfo; + VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo{}; + pipelineViewportStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + pipelineViewportStateCreateInfo.viewportCount = viewportCount; + pipelineViewportStateCreateInfo.scissorCount = scissorCount; + pipelineViewportStateCreateInfo.flags = flags; + return pipelineViewportStateCreateInfo; } inline VkPipelineMultisampleStateCreateInfo @@ -528,13 +530,13 @@ pipelineMultisampleStateCreateInfo( VkSampleCountFlagBits rasterizationSamples, VkPipelineMultisampleStateCreateFlags flags = 0) { - VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo{}; - pipelineMultisampleStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - pipelineMultisampleStateCreateInfo.rasterizationSamples = - rasterizationSamples; - pipelineMultisampleStateCreateInfo.flags = flags; - return pipelineMultisampleStateCreateInfo; + VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo{}; + pipelineMultisampleStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + pipelineMultisampleStateCreateInfo.rasterizationSamples = + rasterizationSamples; + pipelineMultisampleStateCreateInfo.flags = flags; + return pipelineMultisampleStateCreateInfo; } inline VkPipelineDynamicStateCreateInfo @@ -542,13 +544,13 @@ pipelineDynamicStateCreateInfo(const VkDynamicState* pDynamicStates, uint32_t dynamicStateCount, VkPipelineDynamicStateCreateFlags flags = 0) { - VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo{}; - pipelineDynamicStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates; - pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount; - pipelineDynamicStateCreateInfo.flags = flags; - return pipelineDynamicStateCreateInfo; + VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo{}; + pipelineDynamicStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates; + pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount; + pipelineDynamicStateCreateInfo.flags = flags; + return pipelineDynamicStateCreateInfo; } inline VkPipelineDynamicStateCreateInfo @@ -556,24 +558,24 @@ pipelineDynamicStateCreateInfo( const std::vector& pDynamicStates, VkPipelineDynamicStateCreateFlags flags = 0) { - VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo{}; - pipelineDynamicStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates.data(); - pipelineDynamicStateCreateInfo.dynamicStateCount = - static_cast(pDynamicStates.size()); - pipelineDynamicStateCreateInfo.flags = flags; - return pipelineDynamicStateCreateInfo; + VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo{}; + pipelineDynamicStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates.data(); + pipelineDynamicStateCreateInfo.dynamicStateCount = + static_cast(pDynamicStates.size()); + pipelineDynamicStateCreateInfo.flags = flags; + return pipelineDynamicStateCreateInfo; } inline VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo(uint32_t patchControlPoints) { - VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo{}; - pipelineTessellationStateCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; - pipelineTessellationStateCreateInfo.patchControlPoints = patchControlPoints; - return pipelineTessellationStateCreateInfo; + VkPipelineTessellationStateCreateInfo pipelineTessellationStateCreateInfo{}; + pipelineTessellationStateCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; + pipelineTessellationStateCreateInfo.patchControlPoints = patchControlPoints; + return pipelineTessellationStateCreateInfo; } inline VkGraphicsPipelineCreateInfo @@ -581,65 +583,65 @@ pipelineCreateInfo(VkPipelineLayout layout, VkRenderPass renderPass, VkPipelineCreateFlags flags = 0) { - VkGraphicsPipelineCreateInfo pipelineCreateInfo{}; - pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipelineCreateInfo.layout = layout; - pipelineCreateInfo.renderPass = renderPass; - pipelineCreateInfo.flags = flags; - pipelineCreateInfo.basePipelineIndex = -1; - pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; - return pipelineCreateInfo; + VkGraphicsPipelineCreateInfo pipelineCreateInfo{}; + pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineCreateInfo.layout = layout; + pipelineCreateInfo.renderPass = renderPass; + pipelineCreateInfo.flags = flags; + pipelineCreateInfo.basePipelineIndex = -1; + pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; + return pipelineCreateInfo; } inline VkGraphicsPipelineCreateInfo pipelineCreateInfo() { - VkGraphicsPipelineCreateInfo pipelineCreateInfo{}; - pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - pipelineCreateInfo.basePipelineIndex = -1; - pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; - return pipelineCreateInfo; + VkGraphicsPipelineCreateInfo pipelineCreateInfo{}; + pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + pipelineCreateInfo.basePipelineIndex = -1; + pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE; + return pipelineCreateInfo; } inline VkComputePipelineCreateInfo computePipelineCreateInfo(VkPipelineLayout layout, VkPipelineCreateFlags flags = 0) { - VkComputePipelineCreateInfo computePipelineCreateInfo{}; - computePipelineCreateInfo.sType = - VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - computePipelineCreateInfo.layout = layout; - computePipelineCreateInfo.flags = flags; - return computePipelineCreateInfo; + VkComputePipelineCreateInfo computePipelineCreateInfo{}; + computePipelineCreateInfo.sType = + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + computePipelineCreateInfo.layout = layout; + computePipelineCreateInfo.flags = flags; + return computePipelineCreateInfo; } inline VkPushConstantRange pushConstantRange(VkShaderStageFlags stageFlags, uint32_t size, uint32_t offset) { - VkPushConstantRange pushConstantRange{}; - pushConstantRange.stageFlags = stageFlags; - pushConstantRange.offset = offset; - pushConstantRange.size = size; - return pushConstantRange; + VkPushConstantRange pushConstantRange{}; + pushConstantRange.stageFlags = stageFlags; + pushConstantRange.offset = offset; + pushConstantRange.size = size; + return pushConstantRange; } inline VkBindSparseInfo bindSparseInfo() { - VkBindSparseInfo bindSparseInfo{}; - bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO; - return bindSparseInfo; + VkBindSparseInfo bindSparseInfo{}; + bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO; + return bindSparseInfo; } /** @brief Initialize a map entry for a shader specialization constant */ inline VkSpecializationMapEntry specializationMapEntry(uint32_t constantID, uint32_t offset, size_t size) { - VkSpecializationMapEntry specializationMapEntry{}; - specializationMapEntry.constantID = constantID; - specializationMapEntry.offset = offset; - specializationMapEntry.size = size; - return specializationMapEntry; + VkSpecializationMapEntry specializationMapEntry{}; + specializationMapEntry.constantID = constantID; + specializationMapEntry.offset = offset; + specializationMapEntry.size = size; + return specializationMapEntry; } /** @brief Initialize a specialization constant info structure to pass to a @@ -650,12 +652,12 @@ specializationInfo(uint32_t mapEntryCount, size_t dataSize, const void* data) { - VkSpecializationInfo specializationInfo{}; - specializationInfo.mapEntryCount = mapEntryCount; - specializationInfo.pMapEntries = mapEntries; - specializationInfo.dataSize = dataSize; - specializationInfo.pData = data; - return specializationInfo; + VkSpecializationInfo specializationInfo{}; + specializationInfo.mapEntryCount = mapEntryCount; + specializationInfo.pMapEntries = mapEntries; + specializationInfo.dataSize = dataSize; + specializationInfo.pData = data; + return specializationInfo; } /** @brief Initialize a specialization constant info structure to pass to a @@ -665,12 +667,12 @@ specializationInfo(const std::vector& mapEntries, size_t dataSize, const void* data) { - VkSpecializationInfo specializationInfo{}; - specializationInfo.mapEntryCount = static_cast(mapEntries.size()); - specializationInfo.pMapEntries = mapEntries.data(); - specializationInfo.dataSize = dataSize; - specializationInfo.pData = data; - return specializationInfo; + VkSpecializationInfo specializationInfo{}; + specializationInfo.mapEntryCount = static_cast(mapEntries.size()); + specializationInfo.pMapEntries = mapEntries.data(); + specializationInfo.dataSize = dataSize; + specializationInfo.pData = data; + return specializationInfo; } } // namespace initializers diff --git a/src/VulkanTools.cpp b/src/VulkanTools.cpp index 3b43bca11..963084153 100644 --- a/src/VulkanTools.cpp +++ b/src/VulkanTools.cpp @@ -13,9 +13,9 @@ const std::string getAssetPath() { #if defined(VK_EXAMPLE_DATA_DIR) - return VK_EXAMPLE_DATA_DIR; + return VK_EXAMPLE_DATA_DIR; #else - return "./../"; + return "./../"; #endif } @@ -26,79 +26,80 @@ bool errorModeSilent = false; std::string errorString(VkResult errorCode) { - switch (errorCode) { + switch (errorCode) { #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_FEATURE_NOT_PRESENT); - STR(ERROR_INCOMPATIBLE_DRIVER); - STR(ERROR_TOO_MANY_OBJECTS); - STR(ERROR_FORMAT_NOT_SUPPORTED); - STR(ERROR_SURFACE_LOST_KHR); - STR(ERROR_NATIVE_WINDOW_IN_USE_KHR); - STR(SUBOPTIMAL_KHR); - STR(ERROR_OUT_OF_DATE_KHR); - STR(ERROR_INCOMPATIBLE_DISPLAY_KHR); - STR(ERROR_VALIDATION_FAILED_EXT); - STR(ERROR_INVALID_SHADER_NV); + 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_FEATURE_NOT_PRESENT); + STR(ERROR_INCOMPATIBLE_DRIVER); + STR(ERROR_TOO_MANY_OBJECTS); + STR(ERROR_FORMAT_NOT_SUPPORTED); + STR(ERROR_SURFACE_LOST_KHR); + STR(ERROR_NATIVE_WINDOW_IN_USE_KHR); + STR(SUBOPTIMAL_KHR); + STR(ERROR_OUT_OF_DATE_KHR); + STR(ERROR_INCOMPATIBLE_DISPLAY_KHR); + STR(ERROR_VALIDATION_FAILED_EXT); + STR(ERROR_INVALID_SHADER_NV); #undef STR - default: - return "UNKNOWN_ERROR"; - } + default: + return "UNKNOWN_ERROR"; + } } std::string physicalDeviceTypeString(VkPhysicalDeviceType type) { - switch (type) { + switch (type) { #define STR(r) \ - case VK_PHYSICAL_DEVICE_TYPE_##r: \ - return #r - STR(OTHER); - STR(INTEGRATED_GPU); - STR(DISCRETE_GPU); - STR(VIRTUAL_GPU); + case VK_PHYSICAL_DEVICE_TYPE_##r: \ + return #r + STR(OTHER); + STR(INTEGRATED_GPU); + STR(DISCRETE_GPU); + STR(VIRTUAL_GPU); #undef STR - default: - return "UNKNOWN_DEVICE_TYPE"; - } + default: + return "UNKNOWN_DEVICE_TYPE"; + } } 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 }; + // 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 }; - 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; + 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; + return false; } // Returns if a given format support LINEAR filtering @@ -107,18 +108,18 @@ formatIsFilterable(VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling) { - VkFormatProperties formatProps; - vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProps); + VkFormatProperties formatProps; + vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProps); - if (tiling == VK_IMAGE_TILING_OPTIMAL) - return formatProps.optimalTilingFeatures & - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + if (tiling == VK_IMAGE_TILING_OPTIMAL) + return formatProps.optimalTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; - if (tiling == VK_IMAGE_TILING_LINEAR) - return formatProps.linearTilingFeatures & - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + if (tiling == VK_IMAGE_TILING_LINEAR) + return formatProps.linearTilingFeatures & + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; - return false; + return false; } // Create an image memory barrier for changing the layout of @@ -134,121 +135,124 @@ setImageLayout(VkCommandBuffer cmdbuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask) { - // Create an image barrier object - VkImageMemoryBarrier imageMemoryBarrier = - vks::initializers::imageMemoryBarrier(); - imageMemoryBarrier.oldLayout = oldImageLayout; - imageMemoryBarrier.newLayout = newImageLayout; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; + // Create an image barrier object + VkImageMemoryBarrier imageMemoryBarrier = + vks::initializers::imageMemoryBarrier(); + imageMemoryBarrier.oldLayout = oldImageLayout; + imageMemoryBarrier.newLayout = newImageLayout; + imageMemoryBarrier.image = image; + imageMemoryBarrier.subresourceRange = subresourceRange; - // Source layouts (old) - // Source access mask controls actions that have to be finished on the old - // layout before it will be transitioned to the new layout - switch (oldImageLayout) { - case VK_IMAGE_LAYOUT_UNDEFINED: - // Image layout is undefined (or does not matter) - // Only valid as initial layout - // No flags required, listed only for completeness - imageMemoryBarrier.srcAccessMask = 0; - break; + // Source layouts (old) + // Source access mask controls actions that have to be finished on the old + // layout before it will be transitioned to the new layout + switch (oldImageLayout) { + case VK_IMAGE_LAYOUT_UNDEFINED: + // Image layout is undefined (or does not matter) + // Only valid as initial layout + // No flags required, listed only for completeness + imageMemoryBarrier.srcAccessMask = 0; + break; - case VK_IMAGE_LAYOUT_PREINITIALIZED: - // Image is preinitialized - // Only valid as initial layout for linear images, preserves memory - // contents Make sure host writes have been finished - imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; - break; + case VK_IMAGE_LAYOUT_PREINITIALIZED: + // Image is preinitialized + // Only valid as initial layout for linear images, preserves memory + // contents Make sure host writes have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + break; - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - // Image is a color attachment - // Make sure any writes to the color buffer have been finished - imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - break; + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + // Image is a color attachment + // Make sure any writes to the color buffer have been finished + imageMemoryBarrier.srcAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + break; - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - // Image is a depth/stencil attachment - // Make sure any writes to the depth/stencil buffer have been finished - imageMemoryBarrier.srcAccessMask = - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - break; + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + // Image is a depth/stencil attachment + // Make sure any writes to the depth/stencil buffer have been + // finished + imageMemoryBarrier.srcAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + break; - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - // Image is a transfer source - // Make sure any reads from the image have been finished - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + // Image is a transfer source + // Make sure any reads from the image have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + break; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - // Image is a transfer destination - // Make sure any writes to the image have been finished - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + // Image is a transfer destination + // Make sure any writes to the image have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + break; - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - // Image is read by a shader - // Make sure any shader reads from the image have been finished - imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - break; - default: - // Other source layouts aren't handled (yet) - break; - } + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + // Image is read by a shader + // Make sure any shader reads from the image have been finished + imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; + default: + // Other source layouts aren't handled (yet) + break; + } - // Target layouts (new) - // Destination access mask controls the dependency for the new image layout - switch (newImageLayout) { - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - // Image will be used as a transfer destination - // Make sure any writes to the image have been finished - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - break; + // Target layouts (new) + // Destination access mask controls the dependency for the new image layout + switch (newImageLayout) { + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + // Image will be used as a transfer destination + // Make sure any writes to the image have been finished + imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + break; - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - // Image will be used as a transfer source - // Make sure any reads from the image have been finished - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + // Image will be used as a transfer source + // Make sure any reads from the image have been finished + imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + break; - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - // Image will be used as a color attachment - // Make sure any writes to the color buffer have been finished - imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - break; + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + // Image will be used as a color attachment + // Make sure any writes to the color buffer have been finished + imageMemoryBarrier.dstAccessMask = + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + break; - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - // Image layout will be used as a depth/stencil attachment - // Make sure any writes to depth/stencil buffer have been finished - imageMemoryBarrier.dstAccessMask = - imageMemoryBarrier.dstAccessMask | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - break; + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + // Image layout will be used as a depth/stencil attachment + // Make sure any writes to depth/stencil buffer have been finished + imageMemoryBarrier.dstAccessMask = + imageMemoryBarrier.dstAccessMask | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + break; - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - // Image will be read in a shader (sampler, input attachment) - // Make sure any writes to the image have been finished - if (imageMemoryBarrier.srcAccessMask == 0) { - imageMemoryBarrier.srcAccessMask = - VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; - } - imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - break; - default: - // Other source layouts aren't handled (yet) - break; - } + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + // Image will be read in a shader (sampler, input attachment) + // Make sure any writes to the image have been finished + if (imageMemoryBarrier.srcAccessMask == 0) { + imageMemoryBarrier.srcAccessMask = + VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT; + } + imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + break; + default: + // Other source layouts aren't handled (yet) + break; + } - // Put barrier inside setup command buffer - vkCmdPipelineBarrier(cmdbuffer, - srcStageMask, - dstStageMask, - 0, - 0, - nullptr, - 0, - nullptr, - 1, - &imageMemoryBarrier); + // Put barrier inside setup command buffer + vkCmdPipelineBarrier(cmdbuffer, + srcStageMask, + dstStageMask, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &imageMemoryBarrier); } // Fixed sub resource on first mip level and layer @@ -261,18 +265,18 @@ setImageLayout(VkCommandBuffer cmdbuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask) { - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = aspectMask; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = 1; - subresourceRange.layerCount = 1; - setImageLayout(cmdbuffer, - image, - oldImageLayout, - newImageLayout, - subresourceRange, - srcStageMask, - dstStageMask); + VkImageSubresourceRange subresourceRange = {}; + subresourceRange.aspectMask = aspectMask; + subresourceRange.baseMipLevel = 0; + subresourceRange.levelCount = 1; + subresourceRange.layerCount = 1; + setImageLayout(cmdbuffer, + image, + oldImageLayout, + newImageLayout, + subresourceRange, + srcStageMask, + dstStageMask); } void @@ -286,82 +290,82 @@ insertImageMemoryBarrier(VkCommandBuffer cmdbuffer, VkPipelineStageFlags dstStageMask, VkImageSubresourceRange subresourceRange) { - VkImageMemoryBarrier imageMemoryBarrier = - vks::initializers::imageMemoryBarrier(); - imageMemoryBarrier.srcAccessMask = srcAccessMask; - imageMemoryBarrier.dstAccessMask = dstAccessMask; - imageMemoryBarrier.oldLayout = oldImageLayout; - imageMemoryBarrier.newLayout = newImageLayout; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; + VkImageMemoryBarrier imageMemoryBarrier = + vks::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); + vkCmdPipelineBarrier(cmdbuffer, + srcStageMask, + dstStageMask, + 0, + 0, + nullptr, + 0, + nullptr, + 1, + &imageMemoryBarrier); } void exitFatal(std::string message, int32_t exitCode) { #if defined(_WIN32) - if (!errorModeSilent) { - MessageBox(NULL, message.c_str(), NULL, MB_OK | MB_ICONERROR); - } + if (!errorModeSilent) { + MessageBox(NULL, message.c_str(), NULL, MB_OK | MB_ICONERROR); + } #endif - std::cerr << message << "\n"; + std::cerr << message << "\n"; } void exitFatal(std::string message, VkResult resultCode) { - exitFatal(message, (int32_t)resultCode); + exitFatal(message, (int32_t)resultCode); } VkShaderModule loadShader(const char* fileName, VkDevice device) { - std::ifstream is(fileName, std::ios::binary | std::ios::in | std::ios::ate); + std::ifstream is(fileName, std::ios::binary | std::ios::in | std::ios::ate); - if (is.is_open()) { - size_t size = is.tellg(); - is.seekg(0, std::ios::beg); - char* shaderCode = new char[size]; - is.read(shaderCode, size); - is.close(); + if (is.is_open()) { + size_t size = is.tellg(); + is.seekg(0, std::ios::beg); + char* shaderCode = new char[size]; + is.read(shaderCode, size); + is.close(); - assert(size > 0); + assert(size > 0); - VkShaderModule shaderModule; - VkShaderModuleCreateInfo moduleCreateInfo{}; - moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleCreateInfo.codeSize = size; - moduleCreateInfo.pCode = (uint32_t*)shaderCode; + VkShaderModule shaderModule; + VkShaderModuleCreateInfo moduleCreateInfo{}; + moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleCreateInfo.codeSize = size; + moduleCreateInfo.pCode = (uint32_t*)shaderCode; - VK_CHECK_RESULT( - vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule)); + VK_CHECK_RESULT( + vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule)); - delete[] shaderCode; + delete[] shaderCode; - return shaderModule; - } else { - std::cerr << "Error: Could not open shader file \"" << fileName << "\"" - << std::endl; - return VK_NULL_HANDLE; - } + return shaderModule; + } else { + std::cerr << "Error: Could not open shader file \"" << fileName << "\"" + << std::endl; + return VK_NULL_HANDLE; + } } bool fileExists(const std::string& filename) { - std::ifstream f(filename.c_str()); - return !f.fail(); + std::ifstream f(filename.c_str()); + return !f.fail(); } } // namespace tools } // namespace vks diff --git a/src/VulkanTools.h b/src/VulkanTools.h index 765ab9b6d..bec00baa7 100644 --- a/src/VulkanTools.h +++ b/src/VulkanTools.h @@ -35,15 +35,15 @@ // Macro to check and display Vulkan return results #define VK_CHECK_RESULT(f) \ - { \ - VkResult res = (f); \ - if (res != VK_SUCCESS) { \ - std::cout << "Fatal : VkResult is \"" << vks::tools::errorString(res) \ - << "\" in " << __FILE__ << " at line " << __LINE__ \ - << std::endl; \ - assert(res == VK_SUCCESS); \ - } \ - } + { \ + VkResult res = (f); \ + if (res != VK_SUCCESS) { \ + std::cout << "Fatal : VkResult is \"" \ + << vks::tools::errorString(res) << "\" in " << __FILE__ \ + << " at line " << __LINE__ << std::endl; \ + assert(res == VK_SUCCESS); \ + } \ + } const std::string getAssetPath(); diff --git a/src/main.cpp b/src/main.cpp index f0c1eac96..1116eeded 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,565 +29,586 @@ debugMessageCallback(VkDebugReportFlagsEXT flags, const char* pMessage, void* pUserData) { - LOG("[VALIDATION]: %s - %s\n", pLayerPrefix, pMessage); - return VK_FALSE; + LOG("[VALIDATION]: %s - %s\n", pLayerPrefix, pMessage); + return VK_FALSE; } class VulkanExample { -public: - VkInstance instance; - VkPhysicalDevice physicalDevice; - VkDevice device; - uint32_t queueFamilyIndex; - VkPipelineCache pipelineCache; - VkQueue queue; - VkCommandPool commandPool; - VkCommandBuffer commandBuffer; - VkFence fence; - VkDescriptorPool descriptorPool; - VkDescriptorSetLayout descriptorSetLayout; - VkDescriptorSet descriptorSet; - VkPipelineLayout pipelineLayout; - VkPipeline pipeline; - VkShaderModule shaderModule; + public: + VkInstance instance; + VkPhysicalDevice physicalDevice; + VkDevice device; + uint32_t queueFamilyIndex; + VkPipelineCache pipelineCache; + VkQueue queue; + VkCommandPool commandPool; + VkCommandBuffer commandBuffer; + VkFence fence; + VkDescriptorPool descriptorPool; + VkDescriptorSetLayout descriptorSetLayout; + VkDescriptorSet descriptorSet; + VkPipelineLayout pipelineLayout; + VkPipeline pipeline; + VkShaderModule shaderModule; - VkDebugReportCallbackEXT debugReportCallback{}; + VkDebugReportCallbackEXT debugReportCallback{}; - VkResult createBuffer(VkBufferUsageFlags usageFlags, - VkMemoryPropertyFlags memoryPropertyFlags, - VkBuffer* buffer, - VkDeviceMemory* memory, - VkDeviceSize size, - void* data = nullptr) - { - // Create the buffer handle - VkBufferCreateInfo bufferCreateInfo = - vks::initializers::bufferCreateInfo(usageFlags, size); - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - VK_CHECK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, buffer)); + VkResult createBuffer(VkBufferUsageFlags usageFlags, + VkMemoryPropertyFlags memoryPropertyFlags, + VkBuffer* buffer, + VkDeviceMemory* memory, + VkDeviceSize size, + void* data = nullptr) + { + // Create the buffer handle + VkBufferCreateInfo bufferCreateInfo = + vks::initializers::bufferCreateInfo(usageFlags, size); + bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + VK_CHECK_RESULT( + vkCreateBuffer(device, &bufferCreateInfo, nullptr, buffer)); - // Create the memory backing up the buffer handle - VkPhysicalDeviceMemoryProperties deviceMemoryProperties; - vkGetPhysicalDeviceMemoryProperties(physicalDevice, - &deviceMemoryProperties); - VkMemoryRequirements memReqs; - VkMemoryAllocateInfo memAlloc = vks::initializers::memoryAllocateInfo(); - vkGetBufferMemoryRequirements(device, *buffer, &memReqs); - memAlloc.allocationSize = memReqs.size; - // Find a memory type index that fits the properties of the buffer - bool memTypeFound = false; - for (uint32_t i = 0; i < deviceMemoryProperties.memoryTypeCount; i++) { - if ((memReqs.memoryTypeBits & 1) == 1) { - if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & - memoryPropertyFlags) == memoryPropertyFlags) { - memAlloc.memoryTypeIndex = i; - memTypeFound = true; + // Create the memory backing up the buffer handle + VkPhysicalDeviceMemoryProperties deviceMemoryProperties; + vkGetPhysicalDeviceMemoryProperties(physicalDevice, + &deviceMemoryProperties); + VkMemoryRequirements memReqs; + VkMemoryAllocateInfo memAlloc = vks::initializers::memoryAllocateInfo(); + vkGetBufferMemoryRequirements(device, *buffer, &memReqs); + memAlloc.allocationSize = memReqs.size; + // Find a memory type index that fits the properties of the buffer + bool memTypeFound = false; + for (uint32_t i = 0; i < deviceMemoryProperties.memoryTypeCount; i++) { + if ((memReqs.memoryTypeBits & 1) == 1) { + if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & + memoryPropertyFlags) == memoryPropertyFlags) { + memAlloc.memoryTypeIndex = i; + memTypeFound = true; + } + } + memReqs.memoryTypeBits >>= 1; } - } - memReqs.memoryTypeBits >>= 1; - } - assert(memTypeFound); - VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, memory)); + assert(memTypeFound); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, memory)); - if (data != nullptr) { - void* mapped; - VK_CHECK_RESULT(vkMapMemory(device, *memory, 0, size, 0, &mapped)); - memcpy(mapped, data, size); - vkUnmapMemory(device, *memory); - } - - VK_CHECK_RESULT(vkBindBufferMemory(device, *buffer, *memory, 0)); - - return VK_SUCCESS; - } - - VulkanExample() - { - LOG("Running headless compute example\n"); - - VkApplicationInfo appInfo = {}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = "Vulkan headless example"; - appInfo.pEngineName = "VulkanExample"; - appInfo.apiVersion = VK_API_VERSION_1_0; - - /* - Vulkan instance creation (without surface extensions) - */ - VkInstanceCreateInfo instanceCreateInfo = {}; - instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instanceCreateInfo.pApplicationInfo = &appInfo; - - uint32_t layerCount = 0; - const char* validationLayers[] = { "VK_LAYER_LUNARG_standard_validation" }; - layerCount = 1; -#if DEBUG - // Check if layers are available - uint32_t instanceLayerCount; - vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr); - std::vector instanceLayers(instanceLayerCount); - vkEnumerateInstanceLayerProperties(&instanceLayerCount, - instanceLayers.data()); - - bool layersAvailable = true; - for (auto layerName : validationLayers) { - bool layerAvailable = false; - for (auto instanceLayer : instanceLayers) { - if (strcmp(instanceLayer.layerName, layerName) == 0) { - layerAvailable = true; - break; + if (data != nullptr) { + void* mapped; + VK_CHECK_RESULT(vkMapMemory(device, *memory, 0, size, 0, &mapped)); + memcpy(mapped, data, size); + vkUnmapMemory(device, *memory); } - } - if (!layerAvailable) { - layersAvailable = false; - break; - } + + VK_CHECK_RESULT(vkBindBufferMemory(device, *buffer, *memory, 0)); + + return VK_SUCCESS; } - if (layersAvailable) { - instanceCreateInfo.ppEnabledLayerNames = validationLayers; - const char* validationExt = VK_EXT_DEBUG_REPORT_EXTENSION_NAME; - instanceCreateInfo.enabledLayerCount = layerCount; - instanceCreateInfo.enabledExtensionCount = 1; - instanceCreateInfo.ppEnabledExtensionNames = &validationExt; - } + VulkanExample() + { + LOG("Running headless compute example\n"); + + VkApplicationInfo appInfo = {}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = "Vulkan headless example"; + appInfo.pEngineName = "VulkanExample"; + appInfo.apiVersion = VK_API_VERSION_1_0; + + /* + Vulkan instance creation (without surface extensions) + */ + VkInstanceCreateInfo instanceCreateInfo = {}; + instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instanceCreateInfo.pApplicationInfo = &appInfo; + + uint32_t layerCount = 0; + const char* validationLayers[] = { + "VK_LAYER_LUNARG_standard_validation" + }; + layerCount = 1; +#if DEBUG + // Check if layers are available + uint32_t instanceLayerCount; + vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr); + std::vector instanceLayers(instanceLayerCount); + vkEnumerateInstanceLayerProperties(&instanceLayerCount, + instanceLayers.data()); + + bool layersAvailable = true; + for (auto layerName : validationLayers) { + bool layerAvailable = false; + for (auto instanceLayer : instanceLayers) { + if (strcmp(instanceLayer.layerName, layerName) == 0) { + layerAvailable = true; + break; + } + } + if (!layerAvailable) { + layersAvailable = false; + break; + } + } + + if (layersAvailable) { + instanceCreateInfo.ppEnabledLayerNames = validationLayers; + const char* validationExt = VK_EXT_DEBUG_REPORT_EXTENSION_NAME; + instanceCreateInfo.enabledLayerCount = layerCount; + instanceCreateInfo.enabledExtensionCount = 1; + instanceCreateInfo.ppEnabledExtensionNames = &validationExt; + } #endif - VK_CHECK_RESULT(vkCreateInstance(&instanceCreateInfo, nullptr, &instance)); + VK_CHECK_RESULT( + vkCreateInstance(&instanceCreateInfo, nullptr, &instance)); #if DEBUG - if (layersAvailable) { - VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo = {}; - debugReportCreateInfo.sType = - VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; - debugReportCreateInfo.flags = - VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; - debugReportCreateInfo.pfnCallback = - (PFN_vkDebugReportCallbackEXT)debugMessageCallback; + if (layersAvailable) { + VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo = {}; + debugReportCreateInfo.sType = + VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + debugReportCreateInfo.flags = + VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; + debugReportCreateInfo.pfnCallback = + (PFN_vkDebugReportCallbackEXT)debugMessageCallback; - // We have to explicitly load this function. - PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = - reinterpret_cast( - vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT")); - assert(vkCreateDebugReportCallbackEXT); - VK_CHECK_RESULT(vkCreateDebugReportCallbackEXT( - instance, &debugReportCreateInfo, nullptr, &debugReportCallback)); - } + // We have to explicitly load this function. + PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = + reinterpret_cast( + vkGetInstanceProcAddr(instance, + "vkCreateDebugReportCallbackEXT")); + assert(vkCreateDebugReportCallbackEXT); + VK_CHECK_RESULT(vkCreateDebugReportCallbackEXT( + instance, &debugReportCreateInfo, nullptr, &debugReportCallback)); + } #endif - /* - Vulkan device creation - */ - // Physical device (always use first) - uint32_t deviceCount = 0; - VK_CHECK_RESULT( - vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr)); - std::vector physicalDevices(deviceCount); - VK_CHECK_RESULT(vkEnumeratePhysicalDevices( - instance, &deviceCount, physicalDevices.data())); - physicalDevice = physicalDevices[0]; + /* + Vulkan device creation + */ + // Physical device (always use first) + uint32_t deviceCount = 0; + VK_CHECK_RESULT( + vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr)); + std::vector physicalDevices(deviceCount); + VK_CHECK_RESULT(vkEnumeratePhysicalDevices( + instance, &deviceCount, physicalDevices.data())); + physicalDevice = physicalDevices[0]; - VkPhysicalDeviceProperties deviceProperties; - vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties); - LOG("GPU: %s\n", deviceProperties.deviceName); + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties); + LOG("GPU: %s\n", deviceProperties.deviceName); - // Request a single compute queue - const float defaultQueuePriority(0.0f); - VkDeviceQueueCreateInfo queueCreateInfo = {}; - uint32_t queueFamilyCount; - vkGetPhysicalDeviceQueueFamilyProperties( - physicalDevice, &queueFamilyCount, nullptr); - std::vector queueFamilyProperties( - queueFamilyCount); - vkGetPhysicalDeviceQueueFamilyProperties( - physicalDevice, &queueFamilyCount, queueFamilyProperties.data()); - for (uint32_t i = 0; - i < static_cast(queueFamilyProperties.size()); - i++) { - if (queueFamilyProperties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) { - queueFamilyIndex = i; - queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = i; - queueCreateInfo.queueCount = 1; - queueCreateInfo.pQueuePriorities = &defaultQueuePriority; - break; - } + // Request a single compute queue + const float defaultQueuePriority(0.0f); + VkDeviceQueueCreateInfo queueCreateInfo = {}; + uint32_t queueFamilyCount; + vkGetPhysicalDeviceQueueFamilyProperties( + physicalDevice, &queueFamilyCount, nullptr); + std::vector queueFamilyProperties( + queueFamilyCount); + vkGetPhysicalDeviceQueueFamilyProperties( + physicalDevice, &queueFamilyCount, queueFamilyProperties.data()); + for (uint32_t i = 0; + i < static_cast(queueFamilyProperties.size()); + i++) { + if (queueFamilyProperties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) { + queueFamilyIndex = i; + queueCreateInfo.sType = + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfo.queueFamilyIndex = i; + queueCreateInfo.queueCount = 1; + queueCreateInfo.pQueuePriorities = &defaultQueuePriority; + break; + } + } + // Create logical device + VkDeviceCreateInfo deviceCreateInfo = {}; + deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + deviceCreateInfo.queueCreateInfoCount = 1; + deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; + VK_CHECK_RESULT( + vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device)); + + // Get a compute queue + vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue); + + // Compute command pool + VkCommandPoolCreateInfo cmdPoolInfo = {}; + cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + cmdPoolInfo.queueFamilyIndex = queueFamilyIndex; + cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + VK_CHECK_RESULT( + vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &commandPool)); + + /* + Prepare storage buffers + */ + std::vector computeInput(BUFFER_ELEMENTS); + std::vector computeOutput(BUFFER_ELEMENTS); + + // Fill input data + uint32_t n = 0; + std::generate( + computeInput.begin(), computeInput.end(), [&n] { return n++; }); + + const VkDeviceSize bufferSize = BUFFER_ELEMENTS * sizeof(uint32_t); + + VkBuffer deviceBuffer, hostBuffer; + VkDeviceMemory deviceMemory, hostMemory; + + // Copy input data to VRAM using a staging buffer + { + createBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + &hostBuffer, + &hostMemory, + bufferSize, + computeInput.data()); + + // Flush writes to host visible buffer + void* mapped; + vkMapMemory(device, hostMemory, 0, VK_WHOLE_SIZE, 0, &mapped); + VkMappedMemoryRange mappedRange = + vks::initializers::mappedMemoryRange(); + mappedRange.memory = hostMemory; + mappedRange.offset = 0; + mappedRange.size = VK_WHOLE_SIZE; + vkFlushMappedMemoryRanges(device, 1, &mappedRange); + vkUnmapMemory(device, hostMemory); + + createBuffer(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + &deviceBuffer, + &deviceMemory, + bufferSize); + + // Copy to staging buffer + VkCommandBufferAllocateInfo cmdBufAllocateInfo = + vks::initializers::commandBufferAllocateInfo( + commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); + VkCommandBuffer copyCmd; + VK_CHECK_RESULT( + vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, ©Cmd)); + VkCommandBufferBeginInfo cmdBufInfo = + vks::initializers::commandBufferBeginInfo(); + VK_CHECK_RESULT(vkBeginCommandBuffer(copyCmd, &cmdBufInfo)); + + VkBufferCopy copyRegion = {}; + copyRegion.size = bufferSize; + vkCmdCopyBuffer(copyCmd, hostBuffer, deviceBuffer, 1, ©Region); + VK_CHECK_RESULT(vkEndCommandBuffer(copyCmd)); + + VkSubmitInfo submitInfo = vks::initializers::submitInfo(); + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = ©Cmd; + VkFenceCreateInfo fenceInfo = + vks::initializers::fenceCreateInfo(VK_FLAGS_NONE); + VkFence fence; + VK_CHECK_RESULT(vkCreateFence(device, &fenceInfo, nullptr, &fence)); + + // Submit to the queue + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence)); + VK_CHECK_RESULT( + vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX)); + + vkDestroyFence(device, fence, nullptr); + vkFreeCommandBuffers(device, commandPool, 1, ©Cmd); + } + + /* + Prepare compute pipeline + */ + { + std::vector poolSizes = { + vks::initializers::descriptorPoolSize( + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1), + }; + + VkDescriptorPoolCreateInfo descriptorPoolInfo = + vks::initializers::descriptorPoolCreateInfo( + static_cast(poolSizes.size()), poolSizes.data(), 1); + VK_CHECK_RESULT(vkCreateDescriptorPool( + device, &descriptorPoolInfo, nullptr, &descriptorPool)); + + std::vector setLayoutBindings = { + vks::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_SHADER_STAGE_COMPUTE_BIT, + 0), + }; + VkDescriptorSetLayoutCreateInfo descriptorLayout = + vks::initializers::descriptorSetLayoutCreateInfo( + setLayoutBindings); + VK_CHECK_RESULT(vkCreateDescriptorSetLayout( + device, &descriptorLayout, nullptr, &descriptorSetLayout)); + + VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = + vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, + 1); + VK_CHECK_RESULT(vkCreatePipelineLayout( + device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout)); + + VkDescriptorSetAllocateInfo allocInfo = + vks::initializers::descriptorSetAllocateInfo( + descriptorPool, &descriptorSetLayout, 1); + VK_CHECK_RESULT( + vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); + + VkDescriptorBufferInfo bufferDescriptor = { deviceBuffer, + 0, + VK_WHOLE_SIZE }; + std::vector computeWriteDescriptorSets = { + vks::initializers::writeDescriptorSet( + descriptorSet, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + 0, + &bufferDescriptor), + }; + vkUpdateDescriptorSets( + device, + static_cast(computeWriteDescriptorSets.size()), + computeWriteDescriptorSets.data(), + 0, + NULL); + + VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {}; + pipelineCacheCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + VK_CHECK_RESULT(vkCreatePipelineCache( + device, &pipelineCacheCreateInfo, nullptr, &pipelineCache)); + + // Create pipeline + VkComputePipelineCreateInfo computePipelineCreateInfo = + vks::initializers::computePipelineCreateInfo(pipelineLayout, 0); + + // Pass SSBO size via specialization constant + struct SpecializationData + { + uint32_t BUFFER_ELEMENT_COUNT = BUFFER_ELEMENTS; + } specializationData; + VkSpecializationMapEntry specializationMapEntry = + vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); + VkSpecializationInfo specializationInfo = + vks::initializers::specializationInfo(1, + &specializationMapEntry, + sizeof(SpecializationData), + &specializationData); + + // TODO: There is no command line arguments parsing (nor Android + // settings) for this example, so we have no way of picking between + // GLSL or HLSL shaders. Hard-code to glsl for now. + const std::string shadersPath = getAssetPath() + "shaders/glsl/"; + std::cout << "Shader path: " << shadersPath << std::endl; + + VkPipelineShaderStageCreateInfo shaderStage = {}; + shaderStage.sType = + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT; + + shaderStage.module = vks::tools::loadShader( + (shadersPath + "computeheadless.comp.spv").c_str(), device); + + shaderStage.pName = "main"; + shaderStage.pSpecializationInfo = &specializationInfo; + shaderModule = shaderStage.module; + + assert(shaderStage.module != VK_NULL_HANDLE); + computePipelineCreateInfo.stage = shaderStage; + VK_CHECK_RESULT(vkCreateComputePipelines(device, + pipelineCache, + 1, + &computePipelineCreateInfo, + nullptr, + &pipeline)); + + // Create a command buffer for compute operations + VkCommandBufferAllocateInfo cmdBufAllocateInfo = + vks::initializers::commandBufferAllocateInfo( + commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); + VK_CHECK_RESULT(vkAllocateCommandBuffers( + device, &cmdBufAllocateInfo, &commandBuffer)); + + // Fence for compute CB sync + VkFenceCreateInfo fenceCreateInfo = + vks::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT); + VK_CHECK_RESULT( + vkCreateFence(device, &fenceCreateInfo, nullptr, &fence)); + } + + /* + Command buffer creation (for compute work submission) + */ + { + VkCommandBufferBeginInfo cmdBufInfo = + vks::initializers::commandBufferBeginInfo(); + + VK_CHECK_RESULT(vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)); + + // Barrier to ensure that input buffer transfer is finished before + // compute shader reads from it + VkBufferMemoryBarrier bufferBarrier = + vks::initializers::bufferMemoryBarrier(); + bufferBarrier.buffer = deviceBuffer; + bufferBarrier.size = VK_WHOLE_SIZE; + bufferBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; + bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + + vkCmdPipelineBarrier(commandBuffer, + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_FLAGS_NONE, + 0, + nullptr, + 1, + &bufferBarrier, + 0, + nullptr); + + vkCmdBindPipeline( + commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); + vkCmdBindDescriptorSets(commandBuffer, + VK_PIPELINE_BIND_POINT_COMPUTE, + pipelineLayout, + 0, + 1, + &descriptorSet, + 0, + 0); + + vkCmdDispatch(commandBuffer, BUFFER_ELEMENTS, 1, 1); + + // Barrier to ensure that shader writes are finished before buffer + // is read back from GPU + bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + bufferBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + bufferBarrier.buffer = deviceBuffer; + bufferBarrier.size = VK_WHOLE_SIZE; + bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + + vkCmdPipelineBarrier(commandBuffer, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_FLAGS_NONE, + 0, + nullptr, + 1, + &bufferBarrier, + 0, + nullptr); + + // Read back to host visible buffer + VkBufferCopy copyRegion = {}; + copyRegion.size = bufferSize; + vkCmdCopyBuffer( + commandBuffer, deviceBuffer, hostBuffer, 1, ©Region); + + // Barrier to ensure that buffer copy is finished before host + // reading from it + bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + bufferBarrier.buffer = hostBuffer; + bufferBarrier.size = VK_WHOLE_SIZE; + bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + + vkCmdPipelineBarrier(commandBuffer, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, + VK_FLAGS_NONE, + 0, + nullptr, + 1, + &bufferBarrier, + 0, + nullptr); + + VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); + + // Submit compute work + vkResetFences(device, 1, &fence); + const VkPipelineStageFlags waitStageMask = + VK_PIPELINE_STAGE_TRANSFER_BIT; + VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo(); + computeSubmitInfo.pWaitDstStageMask = &waitStageMask; + computeSubmitInfo.commandBufferCount = 1; + computeSubmitInfo.pCommandBuffers = &commandBuffer; + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &computeSubmitInfo, fence)); + VK_CHECK_RESULT( + vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX)); + + // Make device writes visible to the host + void* mapped; + vkMapMemory(device, hostMemory, 0, VK_WHOLE_SIZE, 0, &mapped); + VkMappedMemoryRange mappedRange = + vks::initializers::mappedMemoryRange(); + mappedRange.memory = hostMemory; + mappedRange.offset = 0; + mappedRange.size = VK_WHOLE_SIZE; + vkInvalidateMappedMemoryRanges(device, 1, &mappedRange); + + // Copy to output + memcpy(computeOutput.data(), mapped, bufferSize); + vkUnmapMemory(device, hostMemory); + } + + vkQueueWaitIdle(queue); + + // Output buffer contents + LOG("Compute input:\n"); + for (auto v : computeInput) { + LOG("%d ", v); + } + std::cout << std::endl; + + LOG("Compute output:\n"); + for (auto v : computeOutput) { + LOG("%d ", v); + } + std::cout << std::endl; + + // Clean up + vkDestroyBuffer(device, deviceBuffer, nullptr); + vkFreeMemory(device, deviceMemory, nullptr); + vkDestroyBuffer(device, hostBuffer, nullptr); + vkFreeMemory(device, hostMemory, nullptr); } - // Create logical device - VkDeviceCreateInfo deviceCreateInfo = {}; - deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - deviceCreateInfo.queueCreateInfoCount = 1; - deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; - VK_CHECK_RESULT( - vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device)); - // Get a compute queue - vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue); - - // Compute command pool - VkCommandPoolCreateInfo cmdPoolInfo = {}; - cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - cmdPoolInfo.queueFamilyIndex = queueFamilyIndex; - cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - VK_CHECK_RESULT( - vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &commandPool)); - - /* - Prepare storage buffers - */ - std::vector computeInput(BUFFER_ELEMENTS); - std::vector computeOutput(BUFFER_ELEMENTS); - - // Fill input data - uint32_t n = 0; - std::generate( - computeInput.begin(), computeInput.end(), [&n] { return n++; }); - - const VkDeviceSize bufferSize = BUFFER_ELEMENTS * sizeof(uint32_t); - - VkBuffer deviceBuffer, hostBuffer; - VkDeviceMemory deviceMemory, hostMemory; - - // Copy input data to VRAM using a staging buffer + ~VulkanExample() { - createBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - &hostBuffer, - &hostMemory, - bufferSize, - computeInput.data()); - - // Flush writes to host visible buffer - void* mapped; - vkMapMemory(device, hostMemory, 0, VK_WHOLE_SIZE, 0, &mapped); - VkMappedMemoryRange mappedRange = vks::initializers::mappedMemoryRange(); - mappedRange.memory = hostMemory; - mappedRange.offset = 0; - mappedRange.size = VK_WHOLE_SIZE; - vkFlushMappedMemoryRanges(device, 1, &mappedRange); - vkUnmapMemory(device, hostMemory); - - createBuffer(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_SRC_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - &deviceBuffer, - &deviceMemory, - bufferSize); - - // Copy to staging buffer - VkCommandBufferAllocateInfo cmdBufAllocateInfo = - vks::initializers::commandBufferAllocateInfo( - commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); - VkCommandBuffer copyCmd; - VK_CHECK_RESULT( - vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, ©Cmd)); - VkCommandBufferBeginInfo cmdBufInfo = - vks::initializers::commandBufferBeginInfo(); - VK_CHECK_RESULT(vkBeginCommandBuffer(copyCmd, &cmdBufInfo)); - - VkBufferCopy copyRegion = {}; - copyRegion.size = bufferSize; - vkCmdCopyBuffer(copyCmd, hostBuffer, deviceBuffer, 1, ©Region); - VK_CHECK_RESULT(vkEndCommandBuffer(copyCmd)); - - VkSubmitInfo submitInfo = vks::initializers::submitInfo(); - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = ©Cmd; - VkFenceCreateInfo fenceInfo = - vks::initializers::fenceCreateInfo(VK_FLAGS_NONE); - VkFence fence; - VK_CHECK_RESULT(vkCreateFence(device, &fenceInfo, nullptr, &fence)); - - // Submit to the queue - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence)); - VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX)); - - vkDestroyFence(device, fence, nullptr); - vkFreeCommandBuffers(device, commandPool, 1, ©Cmd); - } - - /* - Prepare compute pipeline - */ - { - std::vector poolSizes = { - vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - 1), - }; - - VkDescriptorPoolCreateInfo descriptorPoolInfo = - vks::initializers::descriptorPoolCreateInfo( - static_cast(poolSizes.size()), poolSizes.data(), 1); - VK_CHECK_RESULT(vkCreateDescriptorPool( - device, &descriptorPoolInfo, nullptr, &descriptorPool)); - - std::vector setLayoutBindings = { - vks::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT, 0), - }; - VkDescriptorSetLayoutCreateInfo descriptorLayout = - vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); - VK_CHECK_RESULT(vkCreateDescriptorSetLayout( - device, &descriptorLayout, nullptr, &descriptorSetLayout)); - - VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = - vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); - VK_CHECK_RESULT(vkCreatePipelineLayout( - device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout)); - - VkDescriptorSetAllocateInfo allocInfo = - vks::initializers::descriptorSetAllocateInfo( - descriptorPool, &descriptorSetLayout, 1); - VK_CHECK_RESULT( - vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); - - VkDescriptorBufferInfo bufferDescriptor = { deviceBuffer, - 0, - VK_WHOLE_SIZE }; - std::vector computeWriteDescriptorSets = { - vks::initializers::writeDescriptorSet(descriptorSet, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - 0, - &bufferDescriptor), - }; - vkUpdateDescriptorSets( - device, - static_cast(computeWriteDescriptorSets.size()), - computeWriteDescriptorSets.data(), - 0, - NULL); - - VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {}; - pipelineCacheCreateInfo.sType = - VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - VK_CHECK_RESULT(vkCreatePipelineCache( - device, &pipelineCacheCreateInfo, nullptr, &pipelineCache)); - - // Create pipeline - VkComputePipelineCreateInfo computePipelineCreateInfo = - vks::initializers::computePipelineCreateInfo(pipelineLayout, 0); - - // Pass SSBO size via specialization constant - struct SpecializationData - { - uint32_t BUFFER_ELEMENT_COUNT = BUFFER_ELEMENTS; - } specializationData; - VkSpecializationMapEntry specializationMapEntry = - vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); - VkSpecializationInfo specializationInfo = - vks::initializers::specializationInfo(1, - &specializationMapEntry, - sizeof(SpecializationData), - &specializationData); - - // TODO: There is no command line arguments parsing (nor Android settings) - // for this example, so we have no way of picking between GLSL or HLSL - // shaders. Hard-code to glsl for now. - const std::string shadersPath = getAssetPath() + "shaders/glsl/"; - std::cout << "Shader path: " << shadersPath << std::endl; - - VkPipelineShaderStageCreateInfo shaderStage = {}; - shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT; - - shaderStage.module = vks::tools::loadShader( - (shadersPath + "computeheadless.comp.spv").c_str(), device); - - shaderStage.pName = "main"; - shaderStage.pSpecializationInfo = &specializationInfo; - shaderModule = shaderStage.module; - - assert(shaderStage.module != VK_NULL_HANDLE); - computePipelineCreateInfo.stage = shaderStage; - VK_CHECK_RESULT(vkCreateComputePipelines(device, - pipelineCache, - 1, - &computePipelineCreateInfo, - nullptr, - &pipeline)); - - // Create a command buffer for compute operations - VkCommandBufferAllocateInfo cmdBufAllocateInfo = - vks::initializers::commandBufferAllocateInfo( - commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1); - VK_CHECK_RESULT( - vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, &commandBuffer)); - - // Fence for compute CB sync - VkFenceCreateInfo fenceCreateInfo = - vks::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT); - VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence)); - } - - /* - Command buffer creation (for compute work submission) - */ - { - VkCommandBufferBeginInfo cmdBufInfo = - vks::initializers::commandBufferBeginInfo(); - - VK_CHECK_RESULT(vkBeginCommandBuffer(commandBuffer, &cmdBufInfo)); - - // Barrier to ensure that input buffer transfer is finished before compute - // shader reads from it - VkBufferMemoryBarrier bufferBarrier = - vks::initializers::bufferMemoryBarrier(); - bufferBarrier.buffer = deviceBuffer; - bufferBarrier.size = VK_WHOLE_SIZE; - bufferBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; - bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - - vkCmdPipelineBarrier(commandBuffer, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_FLAGS_NONE, - 0, - nullptr, - 1, - &bufferBarrier, - 0, - nullptr); - - vkCmdBindPipeline( - commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); - vkCmdBindDescriptorSets(commandBuffer, - VK_PIPELINE_BIND_POINT_COMPUTE, - pipelineLayout, - 0, - 1, - &descriptorSet, - 0, - 0); - - vkCmdDispatch(commandBuffer, BUFFER_ELEMENTS, 1, 1); - - // Barrier to ensure that shader writes are finished before buffer is read - // back from GPU - bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - bufferBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - bufferBarrier.buffer = deviceBuffer; - bufferBarrier.size = VK_WHOLE_SIZE; - bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - - vkCmdPipelineBarrier(commandBuffer, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_FLAGS_NONE, - 0, - nullptr, - 1, - &bufferBarrier, - 0, - nullptr); - - // Read back to host visible buffer - VkBufferCopy copyRegion = {}; - copyRegion.size = bufferSize; - vkCmdCopyBuffer(commandBuffer, deviceBuffer, hostBuffer, 1, ©Region); - - // Barrier to ensure that buffer copy is finished before host reading from - // it - bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - bufferBarrier.buffer = hostBuffer; - bufferBarrier.size = VK_WHOLE_SIZE; - bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - - vkCmdPipelineBarrier(commandBuffer, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_HOST_BIT, - VK_FLAGS_NONE, - 0, - nullptr, - 1, - &bufferBarrier, - 0, - nullptr); - - VK_CHECK_RESULT(vkEndCommandBuffer(commandBuffer)); - - // Submit compute work - vkResetFences(device, 1, &fence); - const VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; - VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo(); - computeSubmitInfo.pWaitDstStageMask = &waitStageMask; - computeSubmitInfo.commandBufferCount = 1; - computeSubmitInfo.pCommandBuffers = &commandBuffer; - VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &computeSubmitInfo, fence)); - VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX)); - - // Make device writes visible to the host - void* mapped; - vkMapMemory(device, hostMemory, 0, VK_WHOLE_SIZE, 0, &mapped); - VkMappedMemoryRange mappedRange = vks::initializers::mappedMemoryRange(); - mappedRange.memory = hostMemory; - mappedRange.offset = 0; - mappedRange.size = VK_WHOLE_SIZE; - vkInvalidateMappedMemoryRanges(device, 1, &mappedRange); - - // Copy to output - memcpy(computeOutput.data(), mapped, bufferSize); - vkUnmapMemory(device, hostMemory); - } - - vkQueueWaitIdle(queue); - - // Output buffer contents - LOG("Compute input:\n"); - for (auto v : computeInput) { - LOG("%d ", v); - } - std::cout << std::endl; - - LOG("Compute output:\n"); - for (auto v : computeOutput) { - LOG("%d ", v); - } - std::cout << std::endl; - - // Clean up - vkDestroyBuffer(device, deviceBuffer, nullptr); - vkFreeMemory(device, deviceMemory, nullptr); - vkDestroyBuffer(device, hostBuffer, nullptr); - vkFreeMemory(device, hostMemory, nullptr); - } - - ~VulkanExample() - { - vkDestroyPipelineLayout(device, pipelineLayout, nullptr); - vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); - vkDestroyDescriptorPool(device, descriptorPool, nullptr); - vkDestroyPipeline(device, pipeline, nullptr); - vkDestroyPipelineCache(device, pipelineCache, nullptr); - vkDestroyFence(device, fence, nullptr); - vkDestroyCommandPool(device, commandPool, nullptr); - vkDestroyShaderModule(device, shaderModule, nullptr); - vkDestroyDevice(device, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); + vkDestroyDescriptorPool(device, descriptorPool, nullptr); + vkDestroyPipeline(device, pipeline, nullptr); + vkDestroyPipelineCache(device, pipelineCache, nullptr); + vkDestroyFence(device, fence, nullptr); + vkDestroyCommandPool(device, commandPool, nullptr); + vkDestroyShaderModule(device, shaderModule, nullptr); + vkDestroyDevice(device, nullptr); #if DEBUG - if (debugReportCallback) { - PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback = - reinterpret_cast( - vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT")); - assert(vkDestroyDebugReportCallback); - vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr); - } + if (debugReportCallback) { + PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback = + reinterpret_cast( + vkGetInstanceProcAddr(instance, + "vkDestroyDebugReportCallbackEXT")); + assert(vkDestroyDebugReportCallback); + vkDestroyDebugReportCallback( + instance, debugReportCallback, nullptr); + } #endif - vkDestroyInstance(instance, nullptr); - } + vkDestroyInstance(instance, nullptr); + } }; int main() { - VulkanExample* vulkanExample = new VulkanExample(); - std::cout << "Finished. Press enter to terminate..."; - getchar(); - delete (vulkanExample); - return 0; + VulkanExample* vulkanExample = new VulkanExample(); + std::cout << "Finished. Press enter to terminate..."; + getchar(); + delete (vulkanExample); + return 0; }