/* * This file is part of libplacebo. * * libplacebo is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * libplacebo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with libplacebo. If not, see . */ #pragma once #include "common.h" // Return a human-readable name for various vulkan enums const char *vk_res_str(VkResult res); const char *vk_fmt_name(VkFormat fmt); const char *vk_csp_name(VkColorSpaceKHR csp); const char *vk_handle_name(VkExternalMemoryHandleTypeFlagBitsKHR handle); const char *vk_obj_type(VkObjectType obj); const char *vk_alpha_mode(VkCompositeAlphaFlagsKHR alpha); const char *vk_surface_transform(VkSurfaceTransformFlagsKHR transform); // Return the size of an arbitrary vulkan struct. Returns 0 for unknown structs size_t vk_struct_size(VkStructureType stype); // Returns the vulkan API version which a given extension was promoted to, or 0 // if the extension is not promoted. uint32_t vk_ext_promoted_ver(const char *extension); // Enum translation boilerplate VkExternalMemoryHandleTypeFlagBitsKHR vk_mem_handle_type(enum pl_handle_type); VkExternalSemaphoreHandleTypeFlagBitsKHR vk_sync_handle_type(enum pl_handle_type); // Bitmask of all access flags that imply a read/write operation, respectively extern const VkAccessFlags2 vk_access_read; extern const VkAccessFlags2 vk_access_write; // Check for compatibility of a VkExternalMemoryProperties bool vk_external_mem_check(struct vk_ctx *vk, const VkExternalMemoryPropertiesKHR *props, enum pl_handle_type handle_type, bool check_import); // Static lists of external handle types we should try probing for extern const enum pl_handle_type vk_mem_handle_list[]; extern const enum pl_handle_type vk_sync_handle_list[]; // Find a structure in a pNext chain, or NULL const void *vk_find_struct(const void *chain, VkStructureType stype); // Link a structure into a pNext chain void vk_link_struct(void *chain, const void *in); // Make a copy of a structure, not including the pNext chain void *vk_struct_memdup(void *alloc, const void *in); // Make a deep copy of an entire pNext chain void *vk_chain_memdup(void *alloc, const void *in); // Find a structure in a pNext chain, or allocate + link it if absent. void *vk_chain_alloc(void *alloc, void *chain, VkStructureType stype); // Renormalize input features into a state consistent for a given API version. // If `api_ver` is specified as 0, *both* meta-structs and extension structs // will be emitted. Note: `out` should be initialized by the user. In // particular, if it already contains a valid features chain, then this // function will effectively act as a union. void vk_features_normalize(void *alloc, const VkPhysicalDeviceFeatures2 *in, uint32_t api_ver, VkPhysicalDeviceFeatures2 *out); // Convenience macros to simplify a lot of common boilerplate #define PL_VK_ASSERT(res, str) \ do { \ if (res != VK_SUCCESS) { \ PL_ERR(vk, str ": %s (%s:%d)", \ vk_res_str(res), __FILE__, __LINE__); \ goto error; \ } \ } while (0) #define VK(cmd) \ do { \ PL_TRACE(vk, #cmd); \ VkResult _res = (cmd); \ PL_VK_ASSERT(_res, #cmd); \ } while (0) #define PL_VK_NAME(type, obj, name) \ do { \ if (vk->SetDebugUtilsObjectNameEXT) { \ vk->SetDebugUtilsObjectNameEXT(vk->dev, &(VkDebugUtilsObjectNameInfoEXT) { \ .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, \ .objectType = VK_OBJECT_TYPE_##type, \ .objectHandle = (uint64_t) (obj), \ .pObjectName = (name), \ }); \ } \ } while (0) // Variant of PL_VK_NAME for dispatchable handles #define PL_VK_NAME_HANDLE(type, obj, name) \ PL_VK_NAME(type, (uintptr_t) (obj), name) // Helper functions to wrap and unwrap non-dispatchable handles into pointers. // Note that wrap/unwrap must always be used linearly. #if VK_USE_64_BIT_PTR_DEFINES == 1 #define vk_wrap_handle(h) (h) #define vk_unwrap_handle(h) (h) #elif UINTPTR_MAX >= UINT64_MAX #define vk_wrap_handle(h) ((void *) (uintptr_t) (h)) #define vk_unwrap_handle(h) ((uint64_t) (uintptr_t) (h)) #else static inline void *vk_wrap_handle(uint64_t h) { uint64_t *wrapper = malloc(sizeof(h)); assert(wrapper); *wrapper = h; return wrapper; } static inline uint64_t vk_unwrap_handle(void *h) { uint64_t *wrapper = h; uint64_t ret = *wrapper; free(wrapper); return ret; } #endif