36 const VkDevice device =
context->getVkDevice();
37 const VkSampleCountFlagBits multisampleCount =
context->getMultisampleCount();
41 constexpr uint32_t viewMask = 0b00000011;
42 constexpr uint32_t correlationMask = 0b00000011;
44 VkRenderPassMultiviewCreateInfo renderPassMultiviewCreateInfo{};
45 renderPassMultiviewCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
46 renderPassMultiviewCreateInfo.subpassCount = 1u;
47 renderPassMultiviewCreateInfo.pViewMasks = &viewMask;
48 renderPassMultiviewCreateInfo.correlationMaskCount = 1u;
49 renderPassMultiviewCreateInfo.pCorrelationMasks = &correlationMask;
51 VkAttachmentDescription colorAttachmentDescription{};
52 colorAttachmentDescription.format = colorFormat;
53 colorAttachmentDescription.samples = multisampleCount;
54 colorAttachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
55 colorAttachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
56 colorAttachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
57 colorAttachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
58 colorAttachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
59 colorAttachmentDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
61 VkAttachmentReference colorAttachmentReference{};
62 colorAttachmentReference.attachment = 0u;
63 colorAttachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
65 VkAttachmentDescription depthAttachmentDescription{};
66 depthAttachmentDescription.format = depthFormat;
67 depthAttachmentDescription.samples = multisampleCount;
68 depthAttachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
69 depthAttachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
70 depthAttachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
71 depthAttachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
74 depthAttachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
75 depthAttachmentDescription.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
77 VkAttachmentReference depthAttachmentReference;
78 depthAttachmentReference.attachment = 1u;
79 depthAttachmentReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
81 VkAttachmentDescription resolveAttachmentDescription{};
82 resolveAttachmentDescription.format = colorFormat;
83 resolveAttachmentDescription.samples = VK_SAMPLE_COUNT_1_BIT;
84 resolveAttachmentDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
85 resolveAttachmentDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
86 resolveAttachmentDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
87 resolveAttachmentDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
91 resolveAttachmentDescription.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
92 resolveAttachmentDescription.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
94 VkAttachmentReference resolveAttachmentReference{};
95 resolveAttachmentReference.attachment = 2u;
96 resolveAttachmentReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
98 VkSubpassDescription subpassDescription{};
99 subpassDescription.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
100 subpassDescription.colorAttachmentCount = 1u;
101 subpassDescription.pColorAttachments = &colorAttachmentReference;
102 subpassDescription.pDepthStencilAttachment = &depthAttachmentReference;
103 subpassDescription.pResolveAttachments = &resolveAttachmentReference;
105 const std::array attachments = {
106 colorAttachmentDescription,
107 depthAttachmentDescription,
108 resolveAttachmentDescription
113 std::array<VkSubpassDependency, 2> dependencies{};
117 dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
118 dependencies[0].dstSubpass = 0;
119 dependencies[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
120 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
121 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
122 dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
123 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
124 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
125 dependencies[0].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
126 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
127 dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
128 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
129 dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
133 dependencies[1].srcSubpass = 0;
134 dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
135 dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
136 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
137 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
139 dependencies[1].dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
140 dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
141 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
142 dependencies[1].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
144 dependencies[1].dependencyFlags = 0;
146 VkRenderPassCreateInfo renderPassCreateInfo{VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
147 renderPassCreateInfo.pNext = &renderPassMultiviewCreateInfo;
148 renderPassCreateInfo.attachmentCount =
static_cast<uint32_t
>(attachments.size());
149 renderPassCreateInfo.pAttachments = attachments.data();
150 renderPassCreateInfo.subpassCount = 1u;
151 renderPassCreateInfo.pSubpasses = &subpassDescription;
152 renderPassCreateInfo.dependencyCount =
static_cast<uint32_t
>(dependencies.size());
153 renderPassCreateInfo.pDependencies = dependencies.data();
154 PLOG_FN_VK(vkCreateRenderPass(
context->getVkDevice(), &renderPassCreateInfo,
nullptr, &
vkRenderPass));
157 PLOGI <<
"Renderpass created!";
160 const uint32_t vkDrawQueueFamilyIndex =
context->getVkGraphicsQueueFamilyIndex();
164 XrGraphicsBindingVulkan2KHR graphicsBinding{XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR};
165 graphicsBinding.device = device;
166 graphicsBinding.instance =
context->getVkInstance();
167 graphicsBinding.physicalDevice =
context->getVkPhysicalDevice();
168 graphicsBinding.queueFamilyIndex = vkDrawQueueFamilyIndex;
169 graphicsBinding.queueIndex = 0u;
171 XrSessionCreateInfo xrSessionCreateInfo{XR_TYPE_SESSION_CREATE_INFO};
172 xrSessionCreateInfo.next = &graphicsBinding;
173 xrSessionCreateInfo.systemId =
context->getXrSystemId();
174 PLOG_THROW_FN_XR(xrCreateSession(
context->getXrInstance(), &xrSessionCreateInfo, &
xrSession));
179 XrReferenceSpaceCreateInfo referenceSpaceCreateInfo{XR_TYPE_REFERENCE_SPACE_CREATE_INFO};
180 referenceSpaceCreateInfo.referenceSpaceType = spaceType;
189 PLOG_THROW_FN_XR(xrEnumerateViewConfigurationViews(
context->getXrInstance(),
context->getXrSystemId(),
196 eyeInfo.type = XR_TYPE_VIEW_CONFIGURATION_VIEW;
197 eyeInfo.next =
nullptr;
200 PLOG_THROW_FN_XR(xrEnumerateViewConfigurationViews(
context->getXrInstance(),
context->getXrSystemId(),
210 eyePose.type = XR_TYPE_VIEW;
211 eyePose.next =
nullptr;
217 uint32_t swapchainFormatCount = 0u;
218 PLOG_FN_XR(xrEnumerateSwapchainFormats(
xrSession, 0u, &swapchainFormatCount,
nullptr));
220 std::vector<int64_t> swapchainFormats(swapchainFormatCount);
221 PLOG_FN_XR(xrEnumerateSwapchainFormats(
xrSession, swapchainFormatCount, &swapchainFormatCount,
222 swapchainFormats.data()));
224 bool doesSwapchainFormatExist =
false;
225 for(
const int64_t& format : swapchainFormats)
227 if(format ==
static_cast<int64_t
>(colorFormat))
229 doesSwapchainFormatExist =
true;
234 if(!doesSwapchainFormatExist)
236 THROW_ERROR(
"Color swapchain format does not exist!");
239 PLOGI <<
"Color format is supported by eyes";
245 uint32_t layerCount = 2u;
250 VkImageCreateInfo imageCreateInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
251 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
252 imageCreateInfo.extent.width = eyeResolution.width;
253 imageCreateInfo.extent.height = eyeResolution.height;
254 imageCreateInfo.extent.depth = 1u;
255 imageCreateInfo.mipLevels = 1u;
256 imageCreateInfo.arrayLayers =
static_cast<uint32_t
>(layerCount);
257 imageCreateInfo.format = colorFormat;
258 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
259 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
260 imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
261 imageCreateInfo.samples = multisampleCount;
262 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
263 PLOG_THROW_FN_VK(vkCreateImage(device, &imageCreateInfo,
nullptr, &
colorBuffer.image));
267 VkImageMemoryRequirementsInfo2 memoryRequirementsInfo{};
268 memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
270 memoryRequirementsInfo.pNext =
nullptr;
272 VkMemoryRequirements2 memoryRequirements{VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
273 vkGetImageMemoryRequirements2(device, &memoryRequirementsInfo, &memoryRequirements);
275 uint32_t suiteableMemoryTypeIndex = 0u;
277 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, suiteableMemoryTypeIndex))
279 THROW_ERROR(
"Could not find a suitable memory type for the image buffer");
283 VkMemoryAllocateInfo memoryAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
284 memoryAllocateInfo.allocationSize = memoryRequirements.memoryRequirements.size;
285 memoryAllocateInfo.memoryTypeIndex = suiteableMemoryTypeIndex;
286 PLOG_FN_VK(vkAllocateMemory(device, &memoryAllocateInfo,
nullptr, &
colorBuffer.deviceMemory));
289 VkBindImageMemoryInfo bindImageMemoryInfo{VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO};
291 bindImageMemoryInfo.memory =
colorBuffer.deviceMemory;
292 bindImageMemoryInfo.memoryOffset = 0u;
293 bindImageMemoryInfo.pNext =
nullptr;
294 PLOG_FN_VK(vkBindImageMemory2(device, 1u, &bindImageMemoryInfo));
297 VkImageViewCreateInfo imageViewCreateInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
299 imageViewCreateInfo.format = colorFormat;
300 imageViewCreateInfo.viewType = (layerCount == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY);
301 imageViewCreateInfo.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
302 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
303 imageViewCreateInfo.subresourceRange.layerCount =
static_cast<uint32_t
>(layerCount);
304 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
305 imageViewCreateInfo.subresourceRange.baseArrayLayer = 0u;
306 imageViewCreateInfo.subresourceRange.baseMipLevel = 0u;
307 imageViewCreateInfo.subresourceRange.levelCount = 1u;
308 PLOG_FN_VK(vkCreateImageView(device, &imageViewCreateInfo,
nullptr, &
colorBuffer.imageView));
311 PLOGI <<
"Created color buffer";
317 VkImageCreateInfo imageCreateInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
318 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
319 imageCreateInfo.extent.width = eyeResolution.width;
320 imageCreateInfo.extent.height = eyeResolution.height;
321 imageCreateInfo.extent.depth = 1u;
322 imageCreateInfo.mipLevels = 1u;
323 imageCreateInfo.arrayLayers =
static_cast<uint32_t
>(layerCount);
324 imageCreateInfo.format = depthFormat;
325 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
326 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
327 imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
328 imageCreateInfo.samples = multisampleCount;
329 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
330 PLOG_FN_VK(vkCreateImage(device, &imageCreateInfo,
nullptr, &
depthBuffer.image));
334 VkImageMemoryRequirementsInfo2 memoryRequirementsInfo;
335 memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
337 memoryRequirementsInfo.pNext =
nullptr;
339 VkMemoryRequirements2 memoryRequirements{VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
340 vkGetImageMemoryRequirements2(device, &memoryRequirementsInfo, &memoryRequirements);
342 uint32_t suiteableMemoryTypeIndex = 0u;
344 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, suiteableMemoryTypeIndex))
346 THROW_ERROR(
"Could not find a suitable memory type for the image buffer");
350 VkMemoryAllocateInfo memoryAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
351 memoryAllocateInfo.allocationSize = memoryRequirements.memoryRequirements.size;
352 memoryAllocateInfo.memoryTypeIndex = suiteableMemoryTypeIndex;
353 PLOG_FN_VK(vkAllocateMemory(device, &memoryAllocateInfo,
nullptr, &
depthBuffer.deviceMemory));
356 VkBindImageMemoryInfo bindImageMemoryInfo{VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO};
358 bindImageMemoryInfo.memory =
depthBuffer.deviceMemory;
359 bindImageMemoryInfo.memoryOffset = 0u;
360 bindImageMemoryInfo.pNext =
nullptr;
361 PLOG_FN_VK(vkBindImageMemory2(device, 1u, &bindImageMemoryInfo));
364 VkImageViewCreateInfo imageViewCreateInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
366 imageViewCreateInfo.format = depthFormat;
367 imageViewCreateInfo.viewType = (layerCount == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY);
368 imageViewCreateInfo.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
369 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
370 imageViewCreateInfo.subresourceRange.layerCount =
static_cast<uint32_t
>(layerCount);
371 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
372 imageViewCreateInfo.subresourceRange.baseArrayLayer = 0u;
373 imageViewCreateInfo.subresourceRange.baseMipLevel = 0u;
374 imageViewCreateInfo.subresourceRange.levelCount = 1u;
375 PLOG_FN_VK(vkCreateImageView(device, &imageViewCreateInfo,
nullptr, &
depthBuffer.imageView));
378 PLOGI <<
"Created depth buffer";
382 PLOGI <<
"Performing initial layout transitions for render target images...";
385 VkCommandPoolCreateInfo poolInfo{VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO};
386 poolInfo.queueFamilyIndex = vkDrawQueueFamilyIndex;
387 poolInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
388 VkCommandPool tempPool;
389 PLOG_FN_VK(vkCreateCommandPool(device, &poolInfo,
nullptr, &tempPool));
400 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
406 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
413 vkDestroyCommandPool(device, tempPool,
nullptr);
414 PLOGI <<
"Initial layout transitions complete.";
419 const XrViewConfigurationView& eyeImageInfo =
eyeImageInfos.at(0u);
421 XrSwapchainCreateInfo xrSwapchainCreateInfo{XR_TYPE_SWAPCHAIN_CREATE_INFO};
422 xrSwapchainCreateInfo.format = colorFormat;
423 xrSwapchainCreateInfo.sampleCount = eyeImageInfo.recommendedSwapchainSampleCount;
424 xrSwapchainCreateInfo.width = eyeImageInfo.recommendedImageRectWidth;
425 xrSwapchainCreateInfo.height = eyeImageInfo.recommendedImageRectHeight;
426 xrSwapchainCreateInfo.arraySize = 2u;
427 xrSwapchainCreateInfo.faceCount = 1u;
428 xrSwapchainCreateInfo.mipCount = 1u;
431 xrSwapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT;
434 PLOGI <<
"OpenXR swapchain created";
439 uint32_t swapchainImageCount;
440 PLOG_FN_XR(xrEnumerateSwapchainImages(
xrSwapchain, 0u, &swapchainImageCount,
nullptr));
442 std::vector<XrSwapchainImageVulkan2KHR> swapchainImages(swapchainImageCount);
443 for(XrSwapchainImageVulkan2KHR& swapchainImage : swapchainImages)
445 swapchainImage.type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR;
448 XrSwapchainImageBaseHeader* data =
reinterpret_cast<XrSwapchainImageBaseHeader*
>(swapchainImages.data());
449 PLOG_FN_XR(xrEnumerateSwapchainImages(
xrSwapchain,
static_cast<uint32_t
>(swapchainImages.size()),
450 &swapchainImageCount, data));
452 PLOGI <<
"Found " << swapchainImages.size() <<
" xr swapchain images!";
455 constexpr uint32_t layerCount = 2u;
457 for(
size_t renderTargetsIndex = 0u; renderTargetsIndex <
swapchainRenderTargets.size(); renderTargetsIndex++)
461 const VkImage image = swapchainImages.at(renderTargetsIndex).image;
463 renderTarget.
image = image;
466 VkImageViewCreateInfo imageViewCreateInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
467 imageViewCreateInfo.image = image;
468 imageViewCreateInfo.format = colorFormat;
469 imageViewCreateInfo.viewType = (layerCount == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY);
470 imageViewCreateInfo.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
471 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
472 imageViewCreateInfo.subresourceRange.layerCount = layerCount;
473 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
474 imageViewCreateInfo.subresourceRange.baseArrayLayer = 0u;
475 imageViewCreateInfo.subresourceRange.baseMipLevel = 0u;
476 imageViewCreateInfo.subresourceRange.levelCount = 1u;
477 PLOG_FN_VK(vkCreateImageView(device, &imageViewCreateInfo,
nullptr, &renderTarget.
imageView));
482 VkFramebufferCreateInfo framebufferCreateInfo{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO};
484 framebufferCreateInfo.attachmentCount =
static_cast<uint32_t
>(attachments.size());
485 framebufferCreateInfo.pAttachments = attachments.data();
486 framebufferCreateInfo.width = eyeResolution.width;
487 framebufferCreateInfo.height = eyeResolution.height;
488 framebufferCreateInfo.layers = 1u;
489 PLOG_FN_VK(vkCreateFramebuffer(device, &framebufferCreateInfo,
nullptr, &renderTarget.
framebuffer));
490 PLOGI <<
"Created Frame buffer";
493 PLOGI <<
"Created swapchain and bound images to multiview";
499 for(
size_t eyeIndex = 0u; eyeIndex <
eyeRenderInfos.size(); eyeIndex++)
501 XrCompositionLayerProjectionView& eyeRenderInfo =
eyeRenderInfos.at(eyeIndex);
502 eyeRenderInfo.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
503 eyeRenderInfo.next =
nullptr;
505 const XrViewConfigurationView& eyeImageInfo =
eyeImageInfos.at(eyeIndex);
507 eyeRenderInfo.subImage.imageArrayIndex =
static_cast<uint32_t
>(eyeIndex);
508 eyeRenderInfo.subImage.imageRect.offset = {0, 0};
509 eyeRenderInfo.subImage.imageRect.extent = {
static_cast<int32_t
>(eyeImageInfo.recommendedImageRectWidth),
510 static_cast<int32_t
>(eyeImageInfo.recommendedImageRectHeight)};