summaryrefslogtreecommitdiffstats
path: root/src/vulkan/utils.h
blob: cb1c5f59020c509a7e67e50633c48e04a659377c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * 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 <http://www.gnu.org/licenses/>.
 */

#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