The open source OpenXR runtime
at mr/scanout-values 104 lines 2.7 kB view raw
1// Copyright 2019-2023, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Sub allocation functions. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup comp_render 8 */ 9 10#include "vk/vk_mini_helpers.h" 11#include "render/render_interface.h" 12 13 14// Align a size with a power of two value. 15static VkDeviceSize 16align_padding_pot(VkDeviceSize size, VkDeviceSize alignment) 17{ 18 return (size + alignment - 1) & ~(alignment - 1); 19} 20 21 22/* 23 * 24 * 'Exported' functions. 25 * 26 */ 27 28void 29render_sub_alloc_tracker_init(struct render_sub_alloc_tracker *rsat, struct render_buffer *buffer) 30{ 31 rsat->buffer = buffer->buffer; 32 rsat->used = 0; 33 rsat->total_size = buffer->size; 34 rsat->mapped = buffer->mapped; 35} 36 37XRT_CHECK_RESULT VkResult 38render_sub_alloc_ubo_alloc_and_get_ptr(struct vk_bundle *vk, 39 struct render_sub_alloc_tracker *rsat, 40 VkDeviceSize size, 41 void **out_ptr, 42 struct render_sub_alloc *out_rsa) 43{ 44 assert(rsat->total_size >= rsat->used); 45 VkDeviceSize space_left = rsat->total_size - rsat->used; 46 47 if (space_left < size) { 48 VK_ERROR(vk, "Can not fit %u in left %u of total %u", (uint32_t)size, (uint32_t)space_left, 49 (uint32_t)rsat->total_size); 50 return VK_ERROR_OUT_OF_DEVICE_MEMORY; 51 } 52 53 // Make sure we align from start of memory. 54 VkDeviceSize padded_used = align_padding_pot(rsat->used + size, RENDER_ALWAYS_SAFE_UBO_ALIGNMENT); 55 56 // Save the current used as offset. 57 VkDeviceSize offset = rsat->used; 58 59 // Ensure used never gets larger then total_size. 60 if (padded_used > rsat->total_size) { 61 rsat->used = rsat->total_size; 62 } else { 63 rsat->used = padded_used; 64 } 65 66 void *ptr = rsat->mapped == NULL ? NULL : (void *)((uint8_t *)rsat->mapped + offset); 67 68 69 /* 70 * All done. 71 */ 72 73 *out_ptr = ptr; 74 *out_rsa = (struct render_sub_alloc){ 75 .buffer = rsat->buffer, 76 .size = size, 77 .offset = offset, 78 }; 79 80 return VK_SUCCESS; 81} 82 83XRT_CHECK_RESULT VkResult 84render_sub_alloc_ubo_alloc_and_write(struct vk_bundle *vk, 85 struct render_sub_alloc_tracker *rsat, 86 const void *src, 87 VkDeviceSize size, 88 struct render_sub_alloc *out_rsa) 89{ 90 VkResult ret; 91 92 if (rsat->mapped == NULL) { 93 VK_ERROR(vk, "Sub allocation not mapped"); 94 return VK_ERROR_OUT_OF_DEVICE_MEMORY; 95 } 96 97 void *dst; 98 ret = render_sub_alloc_ubo_alloc_and_get_ptr(vk, rsat, size, &dst, out_rsa); 99 VK_CHK_AND_RET(ret, "render_sub_alloc_ubo_alloc_and_get_ptr"); 100 101 memcpy(dst, src, size); 102 103 return VK_SUCCESS; 104}