In the Vulkan header vulkan.h
there is a struct defined as
typedef struct VkSwapchainCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkSwapchainCreateFlagsKHR flags;
VkSurfaceKHR surface;
uint32_t minImageCount;
VkFormat imageFormat;
VkColorSpaceKHR imageColorSpace;
VkExtent2D imageExtent;
uint32_t imageArrayLayers;
VkImageUsageFlags imageUsage;
VkSharingMode imageSharingMode;
uint32_t queueFamilyIndexCount;
const uint32_t* pQueueFamilyIndices;
VkSurfaceTransformFlagBitsKHR preTransform;
VkCompositeAlphaFlagBitsKHR compositeAlpha;
VkPresentModeKHR presentMode;
VkBool32 clipped;
VkSwapchainKHR oldSwapchain;
} VkSwapchainCreateInfoKHR;
I've used the following code to see each field's alignment (Visual Studio 2015)
std::cout <<
"sType: " << offsetof(VkSwapchainCreateInfoKHR, sType) << std::endl <<
"pNext: " << offsetof(VkSwapchainCreateInfoKHR, pNext) << std::endl <<
"flags: " << offsetof(VkSwapchainCreateInfoKHR, flags) << std::endl <<
"surface: " << offsetof(VkSwapchainCreateInfoKHR, surface) << std::endl <<
"minImageCount: " << offsetof(VkSwapchainCreateInfoKHR, minImageCount) << std::endl <<
"imageFormat: " << offsetof(VkSwapchainCreateInfoKHR, imageFormat) << std::endl <<
"imageColorSpace: " << offsetof(VkSwapchainCreateInfoKHR, imageColorSpace) << std::endl <<
"imageExtent: " << offsetof(VkSwapchainCreateInfoKHR, imageExtent) << std::endl <<
"imageArrayLayers: " << offsetof(VkSwapchainCreateInfoKHR, imageArrayLayers) << std::endl <<
"imageUsage: " << offsetof(VkSwapchainCreateInfoKHR, imageUsage) << std::endl <<
"imageSharingMode: " << offsetof(VkSwapchainCreateInfoKHR, imageSharingMode) << std::endl <<
"queueFamilyIndexCount: " << offsetof(VkSwapchainCreateInfoKHR, queueFamilyIndexCount) << std::endl <<
"pQueueFamilyIndices: " << offsetof(VkSwapchainCreateInfoKHR, pQueueFamilyIndices) << std::endl <<
"preTransform: " << offsetof(VkSwapchainCreateInfoKHR, preTransform) << std::endl <<
"compositeAlpha: " << offsetof(VkSwapchainCreateInfoKHR, compositeAlpha) << std::endl <<
"presentMode: " << offsetof(VkSwapchainCreateInfoKHR, presentMode) << std::endl <<
"clipped: " << offsetof(VkSwapchainCreateInfoKHR, clipped) << std::endl <<
"oldSwapchain: " << offsetof(VkSwapchainCreateInfoKHR, oldSwapchain) << std::endl <<
std::endl;
And got these results
sType: 0
pNext: 8
flags: 16
surface: 24
minImageCount: 32
imageFormat: 36
imageColorSpace: 40
imageExtent: 44
imageArrayLayers: 52
imageUsageFlags: 56
imageSharingMode: 60
queueFamilyIndexCount: 64
pQueueFamilyIndices: 72
preTransform: 80
compositeAlpha: 84
presentMode: 88
clipped: 92
oldSwapchain: 96
Between the fields flags
and surface
there is an 8 byte gap, even though flags
has an underlying type of uint32_t
. The same is true with the fields queueFamilyIndexCount
and pQueueFamilyIndices
. Why do flags
and queueFamilyIndexCount
take up 8 bytes when they are only 4 bytes wide and every other field of type uint32_t
takes up only 4 bytes? Is there something special about the memory alignment requirements at those offsets?
VkSurfaceKHR
is a non-dispatchable handle. Which, by Vulkan's definitions, is a 64-bit integer. And therefore it must have 8-byte alignment.When structures are being laid out, the compiler will ensure that each member gets the alignment that the type requires. If
surface
had come immediately afterflags
, it would not have 8-byte alignment. Thus, the compiler inserts 4 bytes of padding between the two.