diff --git a/src/vulkan/runtime/meson.build b/src/vulkan/runtime/meson.build index b705a566917..acbe34ece7c 100644 --- a/src/vulkan/runtime/meson.build +++ b/src/vulkan/runtime/meson.build @@ -38,6 +38,8 @@ vulkan_runtime_files = files( 'vk_debug_utils.h', 'vk_deferred_operation.c', 'vk_deferred_operation.h', + 'vk_descriptor_set_layout.c', + 'vk_descriptor_set_layout.h', 'vk_descriptors.c', 'vk_descriptors.h', 'vk_device.c', diff --git a/src/vulkan/runtime/vk_descriptor_set_layout.c b/src/vulkan/runtime/vk_descriptor_set_layout.c new file mode 100644 index 00000000000..6dd46056b75 --- /dev/null +++ b/src/vulkan/runtime/vk_descriptor_set_layout.c @@ -0,0 +1,84 @@ +/* + * Copyright © 2022 Collabora Ltd + * + * 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 "vk_descriptor_set_layout.h" + +#include "vk_alloc.h" +#include "vk_common_entrypoints.h" +#include "vk_device.h" + +static void +vk_descriptor_set_layout_init(struct vk_device *device, + struct vk_descriptor_set_layout *layout) +{ + vk_object_base_init(device, &layout->base, + VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT); + + layout->ref_cnt = 1; +} + +void * +vk_descriptor_set_layout_zalloc(struct vk_device *device, size_t size) +{ + /* Because we're reference counting and lifetimes may not be what the + * client expects, these have to be allocated off the device and not as + * their own object. + */ + struct vk_descriptor_set_layout *layout = + vk_zalloc(&device->alloc, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + + vk_descriptor_set_layout_init(device, layout); + + return layout; +} + +void * +vk_descriptor_set_layout_multizalloc(struct vk_device *device, + struct vk_multialloc *ma) +{ + /* Because we're reference counting and lifetimes may not be what the + * client expects, these have to be allocated off the device and not as + * their own object. + */ + struct vk_descriptor_set_layout *layout = + vk_multialloc_zalloc(ma, &device->alloc, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + + vk_descriptor_set_layout_init(device, layout); + + return layout; +} + +VKAPI_ATTR void VKAPI_CALL +vk_common_DestroyDescriptorSetLayout(VkDevice _device, + VkDescriptorSetLayout descriptorSetLayout, + UNUSED const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(vk_device, device, _device); + VK_FROM_HANDLE(vk_descriptor_set_layout, layout, descriptorSetLayout); + + if (layout == NULL) + return; + + vk_descriptor_set_layout_unref(device, layout); +} diff --git a/src/vulkan/runtime/vk_descriptor_set_layout.h b/src/vulkan/runtime/vk_descriptor_set_layout.h new file mode 100644 index 00000000000..4c43c5e4722 --- /dev/null +++ b/src/vulkan/runtime/vk_descriptor_set_layout.h @@ -0,0 +1,85 @@ +/* + * Copyright © 2022 Collabora Ltd + * + * 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. + */ +#ifndef VK_DESCRIPTOR_SET_LAYOUT_H +#define VK_DESCRIPTOR_SET_LAYOUT_H + +#include "vk_object.h" + +#include "util/u_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct vk_descriptor_set_layout { + struct vk_object_base base; + + /** Reference count + * + * It's often necessary to store a pointer to the descriptor set layout in + * the descriptor so that any entrypoint which has access to a descriptor + * set also has the layout. While layouts are often passed into various + * entrypoints, they're notably missing from vkUpdateDescriptorSets(). In + * order to implement descriptor writes, you either need to stash a pointer + * to the descriptor set layout in the descriptor set or you need to copy + * all of the relevant information. Storing a pointer is a lot cheaper. + * + * Because descriptor set layout lifetimes and descriptor set lifetimes are + * not guaranteed to coincide, we have to reference count if we're going to + * do this. + */ + uint32_t ref_cnt; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(vk_descriptor_set_layout, base, + VkDescriptorSetLayout, + VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT); + +void *vk_descriptor_set_layout_zalloc(struct vk_device *device, size_t size); + +void *vk_descriptor_set_layout_multizalloc(struct vk_device *device, + struct vk_multialloc *ma); + +static inline struct vk_descriptor_set_layout * +vk_descriptor_set_layout_ref(struct vk_descriptor_set_layout *layout) +{ + assert(layout && layout->ref_cnt >= 1); + p_atomic_inc(&layout->ref_cnt); + return layout; +} + +static inline void +vk_descriptor_set_layout_unref(struct vk_device *device, + struct vk_descriptor_set_layout *layout) +{ + assert(layout && layout->ref_cnt >= 1); + if (p_atomic_dec_zero(&layout->ref_cnt)) + vk_object_free(device, NULL, layout); +} + +#ifdef __cplusplus +} +#endif + +#endif /* VK_DESCRIPTOR_SET_LAYOUT_H */ +