The open source OpenXR runtime
at main 144 lines 4.3 kB view raw
1// Copyright 2019-2024, Collabora, Ltd. 2// Copyright 2024-2025, NVIDIA CORPORATION. 3// SPDX-License-Identifier: BSL-1.0 4/*! 5 * @file 6 * @brief Higher level interface for scratch images. 7 * @author Jakob Bornecrantz <tbornecrantz@nvidia.com> 8 * @author Andrei Aristarkhov <aaristarkhov@nvidia.com> 9 * @author Gareth Morgan <gmorgan@nvidia.com> 10 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 11 * @ingroup comp_main 12 */ 13 14 15#include "comp_high_level_scratch.h" 16 17 18void 19chl_scratch_init(struct chl_scratch *scratch) 20{ 21 for (uint32_t i = 0; i < ARRAY_SIZE(scratch->views); i++) { 22 comp_scratch_single_images_init(&scratch->views[i].cssi); 23 } 24} 25 26void 27chl_scratch_fini(struct chl_scratch *scratch) 28{ 29 for (uint32_t i = 0; i < ARRAY_SIZE(scratch->views); i++) { 30 comp_scratch_single_images_destroy(&scratch->views[i].cssi); 31 } 32} 33 34bool 35chl_scratch_ensure(struct chl_scratch *scratch, 36 struct render_resources *rr, 37 uint32_t view_count, 38 VkExtent2D extent, 39 const VkFormat format) 40{ 41 struct vk_bundle *vk = rr->vk; 42 bool bret = false; 43 44 // Is everything already correct? 45 if (scratch->view_count == view_count && // 46 scratch->extent.width == extent.width && // 47 scratch->extent.height == extent.height && // 48 scratch->format == format) { 49 return true; 50 } 51 52 // Free all old resources. 53 chl_scratch_free_resources(scratch, rr); 54 55 // Shared render pass between all scratch images. 56 bret = render_gfx_render_pass_init( // 57 &scratch->render_pass, // rgrp 58 rr, // struct render_resources 59 format, // format 60 VK_ATTACHMENT_LOAD_OP_CLEAR, // load_op 61 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // final_layout 62 if (!bret) { 63 VK_ERROR(vk, "render_gfx_render_pass_init: false"); 64 return false; 65 } 66 67 // Need to track if the render pass has been initialized. 68 scratch->render_pass_initialized = true; 69 70 for (uint32_t i = 0; i < view_count; i++) { 71 // Helper. 72 struct comp_scratch_single_images *cssi = &scratch->views[i].cssi; 73 74 if (format == VK_FORMAT_R8G8B8A8_SRGB) { 75 // Special creation function for the mutable format. 76 bret = comp_scratch_single_images_ensure_mutable(cssi, vk, extent); 77 } else { 78 bret = comp_scratch_single_images_ensure(cssi, vk, extent, format); 79 } 80 81 if (!bret) { 82 VK_ERROR(vk, "comp_scratch_single_images_ensure[_mutable]: false"); 83 // Free any that has already been allocated. 84 chl_scratch_free_resources(scratch, rr); 85 return false; 86 } 87 88 for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) { 89 90 /* 91 * For graphics parts we use the same image view as the 92 * source. In other words the sRGB image view for the 93 * non-linear formats. 94 */ 95 VkImageView target_image_view = chl_scratch_get_sample_view(scratch, i, k); 96 97 render_gfx_target_resources_init( // 98 &scratch->views[i].targets[k], // rtr 99 rr, // struct render_resources 100 &scratch->render_pass, // struct render_gfx_render_pass 101 target_image_view, // target 102 extent); // extent 103 } 104 105 /* 106 * Update the count, doing it this way means free_resources 107 * will free the allocated images correctly. The count is one 108 * more then the index. 109 */ 110 scratch->view_count = i + 1; 111 } 112 113 // Update the cached values. 114 scratch->extent = extent; 115 scratch->format = format; 116 117 return true; 118} 119 120void 121chl_scratch_free_resources(struct chl_scratch *scratch, struct render_resources *rr) 122{ 123 struct vk_bundle *vk = rr->vk; 124 125 for (uint32_t i = 0; i < scratch->view_count; i++) { 126 for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) { 127 render_gfx_target_resources_fini(&scratch->views[i].targets[k]); 128 } 129 130 comp_scratch_single_images_free(&scratch->views[i].cssi, vk); 131 } 132 133 // Nothing allocated. 134 scratch->view_count = 0; 135 scratch->extent.width = 0; 136 scratch->extent.height = 0; 137 scratch->format = VK_FORMAT_UNDEFINED; 138 139 // Do this after the image targets as they reference the render pass. 140 if (scratch->render_pass_initialized) { 141 render_gfx_render_pass_fini(&scratch->render_pass); 142 scratch->render_pass_initialized = false; 143 } 144}