documentation

This commit is contained in:
Jorijn van der Graaf 2025-06-13 23:59:36 +02:00
commit 3275eb2f70
135 changed files with 15649 additions and 430 deletions

660
lib/VulkanInitializers.hpp Normal file
View file

@ -0,0 +1,660 @@
/*
* Initializers for Vulkan structures and objects used by the examples
* Saves lot of VK_STRUCTURE_TYPE assignments
* Some initializers are parameterized for convenience
*
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/
#pragma once
#include <vector>
#include "vulkan/vulkan.h"
namespace vks
{
namespace initializers
{
inline VkMemoryAllocateInfo memoryAllocateInfo()
{
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;
}
inline VkCommandBufferAllocateInfo 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;
}
inline VkCommandPoolCreateInfo commandPoolCreateInfo()
{
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;
}
inline VkCommandBufferInheritanceInfo commandBufferInheritanceInfo()
{
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;
}
inline VkRenderPassCreateInfo 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 */
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;
}
/** @brief Initialize a buffer memory barrier with no image transfer ownership */
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;
}
inline VkMemoryBarrier 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;
}
inline VkSamplerCreateInfo 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;
}
inline VkFramebufferCreateInfo 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;
}
inline VkFenceCreateInfo fenceCreateInfo(VkFenceCreateFlags flags = 0)
{
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;
}
inline VkSubmitInfo 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;
}
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;
}
inline VkBufferCreateInfo bufferCreateInfo()
{
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;
}
inline VkDescriptorPoolCreateInfo 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;
}
inline VkDescriptorPoolCreateInfo descriptorPoolCreateInfo(
const std::vector<VkDescriptorPoolSize>& poolSizes,
uint32_t maxSets)
{
VkDescriptorPoolCreateInfo descriptorPoolInfo{};
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.poolSizeCount = static_cast<uint32_t>(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;
}
inline VkDescriptorSetLayoutBinding descriptorSetLayoutBinding(
VkDescriptorType type,
VkShaderStageFlags stageFlags,
uint32_t binding,
uint32_t descriptorCount = 1)
{
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;
}
inline VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo(
const std::vector<VkDescriptorSetLayoutBinding>& bindings)
{
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{};
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.pBindings = bindings.data();
descriptorSetLayoutCreateInfo.bindingCount = static_cast<uint32_t>(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;
}
inline VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo(
uint32_t setLayoutCount = 1)
{
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{};
pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutCreateInfo.setLayoutCount = setLayoutCount;
return pipelineLayoutCreateInfo;
}
inline VkDescriptorSetAllocateInfo 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;
}
inline VkDescriptorImageInfo descriptorImageInfo(VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout)
{
VkDescriptorImageInfo descriptorImageInfo {};
descriptorImageInfo.sampler = sampler;
descriptorImageInfo.imageView = imageView;
descriptorImageInfo.imageLayout = imageLayout;
return descriptorImageInfo;
}
inline VkWriteDescriptorSet writeDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
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;
}
inline VkWriteDescriptorSet writeDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
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;
}
inline VkVertexInputBindingDescription vertexInputBindingDescription(
uint32_t binding,
uint32_t stride,
VkVertexInputRate inputRate)
{
VkVertexInputBindingDescription vInputBindDescription {};
vInputBindDescription.binding = binding;
vInputBindDescription.stride = stride;
vInputBindDescription.inputRate = inputRate;
return vInputBindDescription;
}
inline VkVertexInputAttributeDescription 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;
}
inline VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo()
{
VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo {};
pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
return pipelineVertexInputStateCreateInfo;
}
inline VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo(
const std::vector<VkVertexInputBindingDescription> &vertexBindingDescriptions,
const std::vector<VkVertexInputAttributeDescription> &vertexAttributeDescriptions
)
{
VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo{};
pipelineVertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
pipelineVertexInputStateCreateInfo.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexBindingDescriptions.size());
pipelineVertexInputStateCreateInfo.pVertexBindingDescriptions = vertexBindingDescriptions.data();
pipelineVertexInputStateCreateInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexAttributeDescriptions.size());
pipelineVertexInputStateCreateInfo.pVertexAttributeDescriptions = vertexAttributeDescriptions.data();
return pipelineVertexInputStateCreateInfo;
}
inline VkPipelineInputAssemblyStateCreateInfo 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;
}
inline VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo(
VkPolygonMode polygonMode,
VkCullModeFlags cullMode,
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;
}
inline VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState(
VkColorComponentFlags colorWriteMask,
VkBool32 blendEnable)
{
VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState {};
pipelineColorBlendAttachmentState.colorWriteMask = colorWriteMask;
pipelineColorBlendAttachmentState.blendEnable = blendEnable;
return pipelineColorBlendAttachmentState;
}
inline VkPipelineColorBlendStateCreateInfo 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;
}
inline VkPipelineDepthStencilStateCreateInfo 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;
pipelineDepthStencilStateCreateInfo.stencilTestEnable = VK_FALSE;
return pipelineDepthStencilStateCreateInfo;
}
inline VkPipelineViewportStateCreateInfo 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;
}
inline VkPipelineMultisampleStateCreateInfo 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;
}
inline VkPipelineDynamicStateCreateInfo 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;
}
inline VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(
const std::vector<VkDynamicState>& pDynamicStates,
VkPipelineDynamicStateCreateFlags flags = 0)
{
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo{};
pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates.data();
pipelineDynamicStateCreateInfo.dynamicStateCount = static_cast<uint32_t>(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;
}
inline VkGraphicsPipelineCreateInfo 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;
}
inline VkGraphicsPipelineCreateInfo 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;
}
inline VkPushConstantRange pushConstantRange(
VkShaderStageFlags stageFlags,
uint32_t size,
uint32_t offset)
{
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;
}
/** @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;
}
/** @brief Initialize a specialization constant info structure to pass to a shader stage */
inline VkSpecializationInfo specializationInfo(uint32_t mapEntryCount, const VkSpecializationMapEntry* mapEntries, size_t dataSize, const void* data)
{
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 shader stage */
inline VkSpecializationInfo specializationInfo(const std::vector<VkSpecializationMapEntry> &mapEntries, size_t dataSize, const void* data)
{
VkSpecializationInfo specializationInfo{};
specializationInfo.mapEntryCount = static_cast<uint32_t>(mapEntries.size());
specializationInfo.pMapEntries = mapEntries.data();
specializationInfo.dataSize = dataSize;
specializationInfo.pData = data;
return specializationInfo;
}
// Ray tracing related
inline VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR()
{
VkAccelerationStructureGeometryKHR accelerationStructureGeometryKHR{};
accelerationStructureGeometryKHR.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
return accelerationStructureGeometryKHR;
}
inline VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR()
{
VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR{};
accelerationStructureBuildGeometryInfoKHR.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
return accelerationStructureBuildGeometryInfoKHR;
}
inline VkAccelerationStructureBuildSizesInfoKHR accelerationStructureBuildSizesInfoKHR()
{
VkAccelerationStructureBuildSizesInfoKHR accelerationStructureBuildSizesInfoKHR{};
accelerationStructureBuildSizesInfoKHR.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
return accelerationStructureBuildSizesInfoKHR;
}
inline VkRayTracingShaderGroupCreateInfoKHR rayTracingShaderGroupCreateInfoKHR()
{
VkRayTracingShaderGroupCreateInfoKHR rayTracingShaderGroupCreateInfoKHR{};
rayTracingShaderGroupCreateInfoKHR.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
return rayTracingShaderGroupCreateInfoKHR;
}
inline VkRayTracingPipelineCreateInfoKHR rayTracingPipelineCreateInfoKHR()
{
VkRayTracingPipelineCreateInfoKHR rayTracingPipelineCreateInfoKHR{};
rayTracingPipelineCreateInfoKHR.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR;
return rayTracingPipelineCreateInfoKHR;
}
inline VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructureKHR()
{
VkWriteDescriptorSetAccelerationStructureKHR writeDescriptorSetAccelerationStructureKHR{};
writeDescriptorSetAccelerationStructureKHR.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
return writeDescriptorSetAccelerationStructureKHR;
}
}
}

455
lib/VulkanTools.cpp Normal file
View file

@ -0,0 +1,455 @@
/*
* Assorted commonly used Vulkan helper functions
*
* Copyright (C) 2016-2024 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/
#include "VulkanTools.h"
#if !(defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT))
// iOS & macOS: getAssetPath() and getShaderBasePath() implemented externally for access to Obj-C++ path utilities
const std::string getAssetPath()
{
if (vks::tools::resourcePath != "") {
return vks::tools::resourcePath + "/assets/";
}
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
return "";
#elif defined(VK_EXAMPLE_ASSETS_DIR)
return VK_EXAMPLE_ASSETS_DIR;
#else
return "./../assets/";
#endif
}
const std::string getShaderBasePath()
{
if (vks::tools::resourcePath != "") {
return vks::tools::resourcePath + "/shaders/";
}
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
return "shaders/";
#elif defined(VK_EXAMPLE_SHADERS_DIR)
return VK_EXAMPLE_SHADERS_DIR;
#else
return "./../shaders/";
#endif
}
#endif
namespace vks
{
namespace tools
{
bool errorModeSilent = false;
std::string resourcePath = "";
std::string errorString(VkResult 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);
STR(ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);
#undef STR
default:
return "UNKNOWN_ERROR";
}
}
std::string physicalDeviceTypeString(VkPhysicalDeviceType 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);
STR(CPU);
#undef STR
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<VkFormat> formatList = {
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 : formatList)
{
VkFormatProperties formatProps;
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProps);
if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
*depthFormat = format;
return true;
}
}
return false;
}
VkBool32 getSupportedDepthStencilFormat(VkPhysicalDevice physicalDevice, VkFormat* depthStencilFormat)
{
std::vector<VkFormat> formatList = {
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D16_UNORM_S8_UINT,
};
for (auto& format : formatList)
{
VkFormatProperties formatProps;
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProps);
if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
*depthStencilFormat = format;
return true;
}
}
return false;
}
VkBool32 formatHasStencil(VkFormat format)
{
std::vector<VkFormat> stencilFormats = {
VK_FORMAT_S8_UINT,
VK_FORMAT_D16_UNORM_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D32_SFLOAT_S8_UINT,
};
return std::find(stencilFormats.begin(), stencilFormats.end(), format) != std::end(stencilFormats);
}
// Returns if a given format support LINEAR filtering
VkBool32 formatIsFilterable(VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
{
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_LINEAR)
return formatProps.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
return false;
}
// 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
void setImageLayout(
VkCommandBuffer cmdbuffer,
VkImage image,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
VkImageSubresourceRange subresourceRange,
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;
// 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_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_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_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;
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_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;
}
// 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
void setImageLayout(
VkCommandBuffer cmdbuffer,
VkImage image,
VkImageAspectFlags aspectMask,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
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);
}
void insertImageMemoryBarrier(
VkCommandBuffer cmdbuffer,
VkImage image,
VkAccessFlags srcAccessMask,
VkAccessFlags dstAccessMask,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
VkPipelineStageFlags srcStageMask,
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;
vkCmdPipelineBarrier(
cmdbuffer,
srcStageMask,
dstStageMask,
0,
0, nullptr,
0, nullptr,
1, &imageMemoryBarrier);
}
void exitFatal(const std::string& message, int32_t exitCode)
{
#if defined(_WIN32)
if (!errorModeSilent) {
MessageBox(NULL, message.c_str(), NULL, MB_OK | MB_ICONERROR);
}
#elif defined(__ANDROID__)
LOGE("Fatal error: %s", message.c_str());
vks::android::showAlert(message.c_str());
#endif
std::cerr << message << "\n";
#if !defined(__ANDROID__)
exit(exitCode);
#endif
}
void exitFatal(const std::string& message, VkResult resultCode)
{
exitFatal(message, (int32_t)resultCode);
}
#if defined(__ANDROID__)
// Android shaders are stored as assets in the apk
// So they need to be loaded via the asset manager
VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device)
{
// Load shader from compressed asset
AAsset* asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_STREAMING);
assert(asset);
size_t size = AAsset_getLength(asset);
assert(size > 0);
char *shaderCode = new char[size];
AAsset_read(asset, shaderCode, size);
AAsset_close(asset);
VkShaderModule shaderModule;
VkShaderModuleCreateInfo moduleCreateInfo;
moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleCreateInfo.pNext = NULL;
moduleCreateInfo.codeSize = size;
moduleCreateInfo.pCode = (uint32_t*)shaderCode;
moduleCreateInfo.flags = 0;
VK_CHECK_RESULT(vkCreateShaderModule(device, &moduleCreateInfo, NULL, &shaderModule));
delete[] shaderCode;
return shaderModule;
}
#else
VkShaderModule loadShader(const char *fileName, VkDevice device)
{
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();
assert(size > 0);
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));
delete[] shaderCode;
return shaderModule;
}
else
{
std::cerr << "Error: Could not open shader file \"" << fileName << "\"" << "\n";
return VK_NULL_HANDLE;
}
}
#endif
bool fileExists(const std::string &filename)
{
std::ifstream f(filename.c_str());
return !f.fail();
}
uint32_t alignedSize(uint32_t value, uint32_t alignment)
{
return (value + alignment - 1) & ~(alignment - 1);
}
size_t alignedSize(size_t value, size_t alignment)
{
return (value + alignment - 1) & ~(alignment - 1);
}
VkDeviceSize alignedVkSize(VkDeviceSize value, VkDeviceSize alignment)
{
return (value + alignment - 1) & ~(alignment - 1);
}
}
}

141
lib/VulkanTools.h Normal file
View file

@ -0,0 +1,141 @@
/*
* Assorted Vulkan helper functions
*
* Copyright (C) 2016-2023 by Sascha Willems - www.saschawillems.de
*
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/
#pragma once
#include "vulkan/vulkan.h"
#include "VulkanInitializers.hpp"
#include <math.h>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <fstream>
#include <assert.h>
#include <stdio.h>
#include <vector>
#include <iostream>
#include <stdexcept>
#include <fstream>
#include <algorithm>
#if defined(_WIN32)
#include <windows.h>
#include <fcntl.h>
#include <io.h>
#elif defined(__ANDROID__)
#include "VulkanAndroid.h"
#include <android/asset_manager.h>
#endif
// Custom define for better code readability
#define VK_FLAGS_NONE 0
// Default fence timeout in nanoseconds
#define DEFAULT_FENCE_TIMEOUT 100000000000
// Macro to check and display Vulkan return results
#if defined(__ANDROID__)
#define VK_CHECK_RESULT(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) \
{ \
LOGE("Fatal : VkResult is \" %s \" in %s at line %d", vks::tools::errorString(res).c_str(), __FILE__, __LINE__); \
assert(res == VK_SUCCESS); \
} \
}
#else
#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__ << "\n"; \
assert(res == VK_SUCCESS); \
} \
}
#endif
const std::string getAssetPath();
const std::string getShaderBasePath();
namespace vks
{
namespace tools
{
/** @brief Setting this path chnanges the place where the samples looks for assets and shaders */
extern std::string resourcePath;
/** @brief Disable message boxes on fatal errors */
extern bool errorModeSilent;
/** @brief Returns an error code as a string */
std::string errorString(VkResult errorCode);
/** @brief Returns the device type as a string */
std::string physicalDeviceTypeString(VkPhysicalDeviceType type);
// Selected a suitable supported depth format starting with 32 bit down to 16 bit
// Returns false if none of the depth formats in the list is supported by the device
VkBool32 getSupportedDepthFormat(VkPhysicalDevice physicalDevice, VkFormat *depthFormat);
// Same as getSupportedDepthFormat but will only select formats that also have stencil
VkBool32 getSupportedDepthStencilFormat(VkPhysicalDevice physicalDevice, VkFormat* depthStencilFormat);
// Returns true a given format support LINEAR filtering
VkBool32 formatIsFilterable(VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling);
// Returns true if a given format has a stencil part
VkBool32 formatHasStencil(VkFormat format);
// Put an image memory barrier for setting an image layout on the sub resource into the given command buffer
void setImageLayout(
VkCommandBuffer cmdbuffer,
VkImage image,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
VkImageSubresourceRange subresourceRange,
VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
// Uses a fixed sub resource layout with first mip level and layer
void setImageLayout(
VkCommandBuffer cmdbuffer,
VkImage image,
VkImageAspectFlags aspectMask,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
/** @brief Insert an image memory barrier into the command buffer */
void insertImageMemoryBarrier(
VkCommandBuffer cmdbuffer,
VkImage image,
VkAccessFlags srcAccessMask,
VkAccessFlags dstAccessMask,
VkImageLayout oldImageLayout,
VkImageLayout newImageLayout,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
VkImageSubresourceRange subresourceRange);
// Display error message and exit on fatal error
void exitFatal(const std::string& message, int32_t exitCode);
void exitFatal(const std::string& message, VkResult resultCode);
// Load a SPIR-V shader (binary)
#if defined(__ANDROID__)
VkShaderModule loadShader(AAssetManager* assetManager, const char *fileName, VkDevice device);
#else
VkShaderModule loadShader(const char *fileName, VkDevice device);
#endif
/** @brief Checks if a file exists */
bool fileExists(const std::string &filename);
uint32_t alignedSize(uint32_t value, uint32_t alignment);
VkDeviceSize alignedVkSize(VkDeviceSize value, VkDeviceSize alignment);
}
}

163
lib/VulkanTransition.hpp Normal file
View file

@ -0,0 +1,163 @@
#include <vulkan/vulkan.h>
VkAccessFlags getAccessFlags(VkImageLayout layout)
{
switch (layout)
{
case VK_IMAGE_LAYOUT_UNDEFINED:
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
return 0;
case VK_IMAGE_LAYOUT_PREINITIALIZED:
return VK_ACCESS_HOST_WRITE_BIT;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR:
return VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
return VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
return VK_ACCESS_TRANSFER_READ_BIT;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
return VK_ACCESS_TRANSFER_WRITE_BIT;
case VK_IMAGE_LAYOUT_GENERAL:
assert(false && "Don't know how to get a meaningful VkAccessFlags for VK_IMAGE_LAYOUT_GENERAL! Don't use it!");
return 0;
default:
assert(false);
return 0;
}
}
VkPipelineStageFlags getPipelineStageFlags(VkImageLayout layout)
{
switch (layout)
{
case VK_IMAGE_LAYOUT_UNDEFINED:
return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
case VK_IMAGE_LAYOUT_PREINITIALIZED:
return VK_PIPELINE_STAGE_HOST_BIT;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
return VK_PIPELINE_STAGE_TRANSFER_BIT;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
return VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
case VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR:
return VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
return VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
case VK_IMAGE_LAYOUT_GENERAL:
assert(false && "Don't know how to get a meaningful VkPipelineStageFlags for VK_IMAGE_LAYOUT_GENERAL! Don't use it!");
return 0;
default:
assert(false);
return 0;
}
}
// Create an image memory barrier for changing the layout of
// an image and put it into an active command buffer
// See chapter 12.4 "Image Layout" for details
void image_layout_transition(VkCommandBuffer command_buffer,
VkImage image,
VkPipelineStageFlags src_stage_mask,
VkPipelineStageFlags dst_stage_mask,
VkAccessFlags src_access_mask,
VkAccessFlags dst_access_mask,
VkImageLayout old_layout,
VkImageLayout new_layout,
VkImageSubresourceRange const &subresource_range)
{
// Create an image barrier object
VkImageMemoryBarrier image_memory_barrier{};
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.srcAccessMask = src_access_mask;
image_memory_barrier.dstAccessMask = dst_access_mask;
image_memory_barrier.oldLayout = old_layout;
image_memory_barrier.newLayout = new_layout;
image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
image_memory_barrier.image = image;
image_memory_barrier.subresourceRange = subresource_range;
// Put barrier inside setup command buffer
vkCmdPipelineBarrier(command_buffer, src_stage_mask, dst_stage_mask, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
}
void image_layout_transition(VkCommandBuffer command_buffer,
VkImage image,
VkImageLayout old_layout,
VkImageLayout new_layout,
VkImageSubresourceRange const &subresource_range)
{
VkPipelineStageFlags src_stage_mask = getPipelineStageFlags(old_layout);
VkPipelineStageFlags dst_stage_mask = getPipelineStageFlags(new_layout);
VkAccessFlags src_access_mask = getAccessFlags(old_layout);
VkAccessFlags dst_access_mask = getAccessFlags(new_layout);
image_layout_transition(command_buffer, image, src_stage_mask, dst_stage_mask, src_access_mask, dst_access_mask, old_layout, new_layout, subresource_range);
}
// Fixed sub resource on first mip level and layer
void image_layout_transition(VkCommandBuffer command_buffer,
VkImage image,
VkImageLayout old_layout,
VkImageLayout new_layout)
{
VkImageSubresourceRange subresource_range = {};
subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresource_range.baseMipLevel = 0;
subresource_range.levelCount = 1;
subresource_range.baseArrayLayer = 0;
subresource_range.layerCount = 1;
image_layout_transition(command_buffer, image, old_layout, new_layout, subresource_range);
}
void image_layout_transition(VkCommandBuffer command_buffer,
std::vector<std::pair<VkImage, VkImageSubresourceRange>> const &imagesAndRanges,
VkImageLayout old_layout,
VkImageLayout new_layout)
{
VkPipelineStageFlags src_stage_mask = getPipelineStageFlags(old_layout);
VkPipelineStageFlags dst_stage_mask = getPipelineStageFlags(new_layout);
VkAccessFlags src_access_mask = getAccessFlags(old_layout);
VkAccessFlags dst_access_mask = getAccessFlags(new_layout);
// Create image barrier objects
std::vector<VkImageMemoryBarrier> image_memory_barriers;
image_memory_barriers.reserve(imagesAndRanges.size());
for (size_t i = 0; i < imagesAndRanges.size(); i++)
{
image_memory_barriers.emplace_back(VkImageMemoryBarrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
nullptr,
src_access_mask,
dst_access_mask,
old_layout,
new_layout,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
imagesAndRanges[i].first,
imagesAndRanges[i].second});
}
// Put barriers inside setup command buffer
vkCmdPipelineBarrier(command_buffer,
src_stage_mask,
dst_stage_mask,
0,
0,
nullptr,
0,
nullptr,
static_cast<uint32_t>(image_memory_barriers.size()),
image_memory_barriers.data());
}

56
lib/shm.c Normal file
View file

@ -0,0 +1,56 @@
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
/**
* Boilerplate to create an in-memory shared file.
*
* Link with `-lrt`.
*/
static void randname(char *buf) {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
long r = ts.tv_nsec;
for (int i = 0; i < 6; ++i) {
buf[i] = 'A'+(r&15)+(r&16)*2;
r >>= 5;
}
}
static int anonymous_shm_open(void) {
char name[] = "/hello-wayland-XXXXXX";
int retries = 100;
do {
randname(name + strlen(name) - 6);
--retries;
// shm_open guarantees that O_CLOEXEC is set
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
if (fd >= 0) {
shm_unlink(name);
return fd;
}
} while (retries > 0 && errno == EEXIST);
return -1;
}
int create_shm_file(off_t size) {
int fd = anonymous_shm_open();
if (fd < 0) {
return fd;
}
if (ftruncate(fd, size) < 0) {
close(fd);
return -1;
}
return fd;
}

10
lib/shm.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef SHM_H
#define SHM_H
#include <sys/types.h>
extern "C" {
int create_shm_file(off_t size);
}
#endif

View file

@ -0,0 +1,76 @@
/* Generated by wayland-scanner 1.23.1 */
/*
* Copyright © 2018 Simon Ser
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface xdg_toplevel_interface;
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
static const struct wl_interface *xdg_decoration_unstable_v1_types[] = {
NULL,
&zxdg_toplevel_decoration_v1_interface,
&xdg_toplevel_interface,
};
static const struct wl_message zxdg_decoration_manager_v1_requests[] = {
{ "destroy", "", xdg_decoration_unstable_v1_types + 0 },
{ "get_toplevel_decoration", "no", xdg_decoration_unstable_v1_types + 1 },
};
WL_PRIVATE const struct wl_interface zxdg_decoration_manager_v1_interface = {
"zxdg_decoration_manager_v1", 1,
2, zxdg_decoration_manager_v1_requests,
0, NULL,
};
static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = {
{ "destroy", "", xdg_decoration_unstable_v1_types + 0 },
{ "set_mode", "u", xdg_decoration_unstable_v1_types + 0 },
{ "unset_mode", "", xdg_decoration_unstable_v1_types + 0 },
};
static const struct wl_message zxdg_toplevel_decoration_v1_events[] = {
{ "configure", "u", xdg_decoration_unstable_v1_types + 0 },
};
WL_PRIVATE const struct wl_interface zxdg_toplevel_decoration_v1_interface = {
"zxdg_toplevel_decoration_v1", 1,
3, zxdg_toplevel_decoration_v1_requests,
1, zxdg_toplevel_decoration_v1_events,
};

View file

@ -0,0 +1,384 @@
/* Generated by wayland-scanner 1.23.1 */
#ifndef XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
#define XDG_DECORATION_UNSTABLE_V1_CLIENT_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page page_xdg_decoration_unstable_v1 The xdg_decoration_unstable_v1 protocol
* @section page_ifaces_xdg_decoration_unstable_v1 Interfaces
* - @subpage page_iface_zxdg_decoration_manager_v1 - window decoration manager
* - @subpage page_iface_zxdg_toplevel_decoration_v1 - decoration object for a toplevel surface
* @section page_copyright_xdg_decoration_unstable_v1 Copyright
* <pre>
*
* Copyright © 2018 Simon Ser
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* </pre>
*/
struct xdg_toplevel;
struct zxdg_decoration_manager_v1;
struct zxdg_toplevel_decoration_v1;
#ifndef ZXDG_DECORATION_MANAGER_V1_INTERFACE
#define ZXDG_DECORATION_MANAGER_V1_INTERFACE
/**
* @page page_iface_zxdg_decoration_manager_v1 zxdg_decoration_manager_v1
* @section page_iface_zxdg_decoration_manager_v1_desc Description
*
* This interface allows a compositor to announce support for server-side
* decorations.
*
* A window decoration is a set of window controls as deemed appropriate by
* the party managing them, such as user interface components used to move,
* resize and change a window's state.
*
* A client can use this protocol to request being decorated by a supporting
* compositor.
*
* If compositor and client do not negotiate the use of a server-side
* decoration using this protocol, clients continue to self-decorate as they
* see fit.
*
* Warning! The protocol described in this file is experimental and
* backward incompatible changes may be made. Backward compatible changes
* may be added together with the corresponding interface version bump.
* Backward incompatible changes are done by bumping the version number in
* the protocol and interface names and resetting the interface version.
* Once the protocol is to be declared stable, the 'z' prefix and the
* version number in the protocol and interface names are removed and the
* interface version number is reset.
* @section page_iface_zxdg_decoration_manager_v1_api API
* See @ref iface_zxdg_decoration_manager_v1.
*/
/**
* @defgroup iface_zxdg_decoration_manager_v1 The zxdg_decoration_manager_v1 interface
*
* This interface allows a compositor to announce support for server-side
* decorations.
*
* A window decoration is a set of window controls as deemed appropriate by
* the party managing them, such as user interface components used to move,
* resize and change a window's state.
*
* A client can use this protocol to request being decorated by a supporting
* compositor.
*
* If compositor and client do not negotiate the use of a server-side
* decoration using this protocol, clients continue to self-decorate as they
* see fit.
*
* Warning! The protocol described in this file is experimental and
* backward incompatible changes may be made. Backward compatible changes
* may be added together with the corresponding interface version bump.
* Backward incompatible changes are done by bumping the version number in
* the protocol and interface names and resetting the interface version.
* Once the protocol is to be declared stable, the 'z' prefix and the
* version number in the protocol and interface names are removed and the
* interface version number is reset.
*/
extern const struct wl_interface zxdg_decoration_manager_v1_interface;
#endif
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
#define ZXDG_TOPLEVEL_DECORATION_V1_INTERFACE
/**
* @page page_iface_zxdg_toplevel_decoration_v1 zxdg_toplevel_decoration_v1
* @section page_iface_zxdg_toplevel_decoration_v1_desc Description
*
* The decoration object allows the compositor to toggle server-side window
* decorations for a toplevel surface. The client can request to switch to
* another mode.
*
* The xdg_toplevel_decoration object must be destroyed before its
* xdg_toplevel.
* @section page_iface_zxdg_toplevel_decoration_v1_api API
* See @ref iface_zxdg_toplevel_decoration_v1.
*/
/**
* @defgroup iface_zxdg_toplevel_decoration_v1 The zxdg_toplevel_decoration_v1 interface
*
* The decoration object allows the compositor to toggle server-side window
* decorations for a toplevel surface. The client can request to switch to
* another mode.
*
* The xdg_toplevel_decoration object must be destroyed before its
* xdg_toplevel.
*/
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
#endif
#define ZXDG_DECORATION_MANAGER_V1_DESTROY 0
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION 1
/**
* @ingroup iface_zxdg_decoration_manager_v1
*/
#define ZXDG_DECORATION_MANAGER_V1_DESTROY_SINCE_VERSION 1
/**
* @ingroup iface_zxdg_decoration_manager_v1
*/
#define ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION_SINCE_VERSION 1
/** @ingroup iface_zxdg_decoration_manager_v1 */
static inline void
zxdg_decoration_manager_v1_set_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zxdg_decoration_manager_v1, user_data);
}
/** @ingroup iface_zxdg_decoration_manager_v1 */
static inline void *
zxdg_decoration_manager_v1_get_user_data(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_decoration_manager_v1);
}
static inline uint32_t
zxdg_decoration_manager_v1_get_version(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1);
}
/**
* @ingroup iface_zxdg_decoration_manager_v1
*
* Destroy the decoration manager. This doesn't destroy objects created
* with the manager.
*/
static inline void
zxdg_decoration_manager_v1_destroy(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
{
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
ZXDG_DECORATION_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), WL_MARSHAL_FLAG_DESTROY);
}
/**
* @ingroup iface_zxdg_decoration_manager_v1
*
* Create a new decoration object associated with the given toplevel.
*
* Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
* buffer attached or committed is a client error, and any attempts by a
* client to attach or manipulate a buffer prior to the first
* xdg_toplevel_decoration.configure event must also be treated as
* errors.
*/
static inline struct zxdg_toplevel_decoration_v1 *
zxdg_decoration_manager_v1_get_toplevel_decoration(struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1, struct xdg_toplevel *toplevel)
{
struct wl_proxy *id;
id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_decoration_manager_v1,
ZXDG_DECORATION_MANAGER_V1_GET_TOPLEVEL_DECORATION, &zxdg_toplevel_decoration_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_decoration_manager_v1), 0, NULL, toplevel);
return (struct zxdg_toplevel_decoration_v1 *) id;
}
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
#define ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM
enum zxdg_toplevel_decoration_v1_error {
/**
* xdg_toplevel has a buffer attached before configure
*/
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0,
/**
* xdg_toplevel already has a decoration object
*/
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1,
/**
* xdg_toplevel destroyed before the decoration object
*/
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2,
/**
* invalid mode
*/
ZXDG_TOPLEVEL_DECORATION_V1_ERROR_INVALID_MODE = 3,
};
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ENUM */
#ifndef ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
#define ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
* window decoration modes
*
* These values describe window decoration modes.
*/
enum zxdg_toplevel_decoration_v1_mode {
/**
* no server-side window decoration
*/
ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1,
/**
* server-side window decoration
*/
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2,
};
#endif /* ZXDG_TOPLEVEL_DECORATION_V1_MODE_ENUM */
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
* @struct zxdg_toplevel_decoration_v1_listener
*/
struct zxdg_toplevel_decoration_v1_listener {
/**
* notify a decoration mode change
*
* The configure event configures the effective decoration mode.
* The configured state should not be applied immediately. Clients
* must send an ack_configure in response to this event. See
* xdg_surface.configure and xdg_surface.ack_configure for details.
*
* A configure event can be sent at any time. The specified mode
* must be obeyed by the client.
* @param mode the decoration mode
*/
void (*configure)(void *data,
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
uint32_t mode);
};
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*/
static inline int
zxdg_toplevel_decoration_v1_add_listener(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
const struct zxdg_toplevel_decoration_v1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zxdg_toplevel_decoration_v1,
(void (**)(void)) listener, data);
}
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY 0
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE 1
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE 2
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*/
#define ZXDG_TOPLEVEL_DECORATION_V1_CONFIGURE_SINCE_VERSION 1
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*/
#define ZXDG_TOPLEVEL_DECORATION_V1_DESTROY_SINCE_VERSION 1
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*/
#define ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE_SINCE_VERSION 1
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*/
#define ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE_SINCE_VERSION 1
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
static inline void
zxdg_toplevel_decoration_v1_set_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data);
}
/** @ingroup iface_zxdg_toplevel_decoration_v1 */
static inline void *
zxdg_toplevel_decoration_v1_get_user_data(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_toplevel_decoration_v1);
}
static inline uint32_t
zxdg_toplevel_decoration_v1_get_version(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1);
}
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*
* Switch back to a mode without any server-side decorations at the next
* commit.
*/
static inline void
zxdg_toplevel_decoration_v1_destroy(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
{
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
ZXDG_TOPLEVEL_DECORATION_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), WL_MARSHAL_FLAG_DESTROY);
}
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*
* Set the toplevel surface decoration mode. This informs the compositor
* that the client prefers the provided decoration mode.
*
* After requesting a decoration mode, the compositor will respond by
* emitting an xdg_surface.configure event. The client should then update
* its content, drawing it without decorations if the received mode is
* server-side decorations. The client must also acknowledge the configure
* when committing the new content (see xdg_surface.ack_configure).
*
* The compositor can decide not to use the client's mode and enforce a
* different mode instead.
*
* Clients whose decoration mode depend on the xdg_toplevel state may send
* a set_mode request in response to an xdg_surface.configure event and wait
* for the next xdg_surface.configure event to prevent unwanted state.
* Such clients are responsible for preventing configure loops and must
* make sure not to send multiple successive set_mode requests with the
* same decoration mode.
*
* If an invalid mode is supplied by the client, the invalid_mode protocol
* error is raised by the compositor.
*/
static inline void
zxdg_toplevel_decoration_v1_set_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode)
{
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
ZXDG_TOPLEVEL_DECORATION_V1_SET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0, mode);
}
/**
* @ingroup iface_zxdg_toplevel_decoration_v1
*
* Unset the toplevel surface decoration mode. This informs the compositor
* that the client doesn't prefer a particular decoration mode.
*
* This request has the same semantics as set_mode.
*/
static inline void
zxdg_toplevel_decoration_v1_unset_mode(struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
{
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_toplevel_decoration_v1,
ZXDG_TOPLEVEL_DECORATION_V1_UNSET_MODE, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_toplevel_decoration_v1), 0);
}
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load diff

184
lib/xdg-shell-protocol.c Normal file
View file

@ -0,0 +1,184 @@
/* Generated by wayland-scanner 1.23.1 */
/*
* Copyright © 2008-2013 Kristian Høgsberg
* Copyright © 2013 Rafael Antognolli
* Copyright © 2013 Jasper St. Pierre
* Copyright © 2010-2013 Intel Corporation
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
* Copyright © 2015-2017 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface xdg_popup_interface;
extern const struct wl_interface xdg_positioner_interface;
extern const struct wl_interface xdg_surface_interface;
extern const struct wl_interface xdg_toplevel_interface;
static const struct wl_interface *xdg_shell_types[] = {
NULL,
NULL,
NULL,
NULL,
&xdg_positioner_interface,
&xdg_surface_interface,
&wl_surface_interface,
&xdg_toplevel_interface,
&xdg_popup_interface,
&xdg_surface_interface,
&xdg_positioner_interface,
&xdg_toplevel_interface,
&wl_seat_interface,
NULL,
NULL,
NULL,
&wl_seat_interface,
NULL,
&wl_seat_interface,
NULL,
NULL,
&wl_output_interface,
&wl_seat_interface,
NULL,
&xdg_positioner_interface,
NULL,
};
static const struct wl_message xdg_wm_base_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "create_positioner", "n", xdg_shell_types + 4 },
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
{ "pong", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_wm_base_events[] = {
{ "ping", "u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
"xdg_wm_base", 6,
4, xdg_wm_base_requests,
1, xdg_wm_base_events,
};
static const struct wl_message xdg_positioner_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_size", "ii", xdg_shell_types + 0 },
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
{ "set_anchor", "u", xdg_shell_types + 0 },
{ "set_gravity", "u", xdg_shell_types + 0 },
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
{ "set_offset", "ii", xdg_shell_types + 0 },
{ "set_reactive", "3", xdg_shell_types + 0 },
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
"xdg_positioner", 6,
10, xdg_positioner_requests,
0, NULL,
};
static const struct wl_message xdg_surface_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "get_toplevel", "n", xdg_shell_types + 7 },
{ "get_popup", "n?oo", xdg_shell_types + 8 },
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
{ "ack_configure", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_surface_events[] = {
{ "configure", "u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
"xdg_surface", 6,
5, xdg_surface_requests,
1, xdg_surface_events,
};
static const struct wl_message xdg_toplevel_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_parent", "?o", xdg_shell_types + 11 },
{ "set_title", "s", xdg_shell_types + 0 },
{ "set_app_id", "s", xdg_shell_types + 0 },
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
{ "move", "ou", xdg_shell_types + 16 },
{ "resize", "ouu", xdg_shell_types + 18 },
{ "set_max_size", "ii", xdg_shell_types + 0 },
{ "set_min_size", "ii", xdg_shell_types + 0 },
{ "set_maximized", "", xdg_shell_types + 0 },
{ "unset_maximized", "", xdg_shell_types + 0 },
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
{ "unset_fullscreen", "", xdg_shell_types + 0 },
{ "set_minimized", "", xdg_shell_types + 0 },
};
static const struct wl_message xdg_toplevel_events[] = {
{ "configure", "iia", xdg_shell_types + 0 },
{ "close", "", xdg_shell_types + 0 },
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
"xdg_toplevel", 6,
14, xdg_toplevel_requests,
4, xdg_toplevel_events,
};
static const struct wl_message xdg_popup_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "grab", "ou", xdg_shell_types + 22 },
{ "reposition", "3ou", xdg_shell_types + 24 },
};
static const struct wl_message xdg_popup_events[] = {
{ "configure", "iiii", xdg_shell_types + 0 },
{ "popup_done", "", xdg_shell_types + 0 },
{ "repositioned", "3u", xdg_shell_types + 0 },
};
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
"xdg_popup", 6,
3, xdg_popup_requests,
3, xdg_popup_events,
};