2
* Copyright © 2017 Intel Corporation
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26
#include "util/bitscan.h"
27
#include "util/macros.h"
28
#include "compiler/shader_enums.h"
36
/* common inlines and macros for vulkan drivers */
38
#include <vulkan/vulkan.h>
40
#define vk_foreach_struct(__iter, __start) \
41
for (struct VkBaseOutStructure *__iter = (struct VkBaseOutStructure *)(__start); \
42
__iter; __iter = __iter->pNext)
44
#define vk_foreach_struct_const(__iter, __start) \
45
for (const struct VkBaseInStructure *__iter = (const struct VkBaseInStructure *)(__start); \
46
__iter; __iter = __iter->pNext)
49
* A wrapper for a Vulkan output array. A Vulkan output array is one that
50
* follows the convention of the parameters to
51
* vkGetPhysicalDeviceQueueFamilyProperties().
56
* vkGetPhysicalDeviceQueueFamilyProperties(
57
* VkPhysicalDevice physicalDevice,
58
* uint32_t* pQueueFamilyPropertyCount,
59
* VkQueueFamilyProperties* pQueueFamilyProperties)
61
* VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties, props,
62
* pQueueFamilyProperties,
63
* pQueueFamilyPropertyCount);
65
* vk_outarray_append_typed(VkQueueFamilyProperties, &props, p) {
66
* p->queueFlags = ...;
67
* p->queueCount = ...;
70
* vk_outarray_append_typed(VkQueueFamilyProperties, &props, p) {
71
* p->queueFlags = ...;
72
* p->queueCount = ...;
75
* return vk_outarray_status(&props);
78
struct __vk_outarray {
83
* Capacity, in number of elements. Capacity is unlimited (UINT32_MAX) if
89
* Count of elements successfully written to the array. Every write is
90
* considered successful if data is null.
95
* Count of elements that would have been written to the array if its
96
* capacity were sufficient. Vulkan functions often return VK_INCOMPLETE
97
* when `*filled_len < wanted_len`.
103
__vk_outarray_init(struct __vk_outarray *a,
104
void *data, uint32_t *restrict len)
116
static inline VkResult
117
__vk_outarray_status(const struct __vk_outarray *a)
119
if (*a->filled_len < a->wanted_len)
120
return VK_INCOMPLETE;
126
__vk_outarray_next(struct __vk_outarray *a, size_t elem_size)
132
if (*a->filled_len >= a->cap)
136
p = (uint8_t *)a->data + (*a->filled_len) * elem_size;
143
#define vk_outarray(elem_t) \
145
struct __vk_outarray base; \
149
#define vk_outarray_typeof_elem(a) __typeof__((a)->meta[0])
150
#define vk_outarray_sizeof_elem(a) sizeof((a)->meta[0])
152
#define vk_outarray_init(a, data, len) \
153
__vk_outarray_init(&(a)->base, (data), (len))
155
#define VK_OUTARRAY_MAKE_TYPED(type, name, data, len) \
156
vk_outarray(type) name; \
157
vk_outarray_init(&name, (data), (len))
159
#define vk_outarray_status(a) \
160
__vk_outarray_status(&(a)->base)
162
#define vk_outarray_next(a) \
163
vk_outarray_next_typed(vk_outarray_typeof_elem(a), a)
164
#define vk_outarray_next_typed(type, a) \
166
__vk_outarray_next(&(a)->base, vk_outarray_sizeof_elem(a)))
169
* Append to a Vulkan output array.
171
* This is a block-based macro. For example:
173
* vk_outarray_append_typed(T, &a, elem) {
178
* The array `a` has type `vk_outarray(elem_t) *`. It is usually declared with
179
* VK_OUTARRAY_MAKE_TYPED(). The variable `elem` is block-scoped and has type
182
* The macro unconditionally increments the array's `wanted_len`. If the array
183
* is not full, then the macro also increment its `filled_len` and then
184
* executes the block. When the block is executed, `elem` is non-null and
185
* points to the newly appended element.
187
#define vk_outarray_append_typed(type, a, elem) \
188
for (type *elem = vk_outarray_next_typed(type, a); \
189
elem != NULL; elem = NULL)
192
__vk_find_struct(void *start, VkStructureType sType)
194
vk_foreach_struct(s, start) {
195
if (s->sType == sType)
202
#define vk_find_struct(__start, __sType) \
203
__vk_find_struct((__start), VK_STRUCTURE_TYPE_##__sType)
205
#define vk_find_struct_const(__start, __sType) \
206
(const void *)__vk_find_struct((void *)(__start), VK_STRUCTURE_TYPE_##__sType)
209
__vk_append_struct(void *start, void *element)
211
vk_foreach_struct(s, start) {
215
s->pNext = (struct VkBaseOutStructure *) element;
220
uint32_t vk_get_driver_version(void);
222
uint32_t vk_get_version_override(void);
224
void vk_warn_non_conformant_implementation(const char *driver_name);
226
struct vk_pipeline_cache_header {
227
uint32_t header_size;
228
uint32_t header_version;
231
uint8_t uuid[VK_UUID_SIZE];
234
#define VK_EXT_OFFSET (1000000000UL)
235
#define VK_ENUM_EXTENSION(__enum) \
236
((__enum) >= VK_EXT_OFFSET ? ((((__enum) - VK_EXT_OFFSET) / 1000UL) + 1) : 0)
237
#define VK_ENUM_OFFSET(__enum) \
238
((__enum) >= VK_EXT_OFFSET ? ((__enum) % 1000) : (__enum))
240
#define typed_memcpy(dest, src, count) do { \
241
STATIC_ASSERT(sizeof(*(src)) == sizeof(*(dest))); \
242
memcpy((dest), (src), (count) * sizeof(*(src))); \
245
static inline gl_shader_stage
246
vk_to_mesa_shader_stage(VkShaderStageFlagBits vk_stage)
248
assert(util_bitcount((uint32_t) vk_stage) == 1);
249
return (gl_shader_stage) (ffs((uint32_t) vk_stage) - 1);
252
static inline VkShaderStageFlagBits
253
mesa_to_vk_shader_stage(gl_shader_stage mesa_stage)
255
return (VkShaderStageFlagBits) (1 << ((uint32_t) mesa_stage));
258
/* iterate over a sequence of indexed multidraws for VK_EXT_multi_draw extension */
259
/* 'i' must be explicitly declared */
260
#define vk_foreach_multi_draw_indexed(_draw, _i, _pDrawInfo, _num_draws, _stride) \
261
for (const VkMultiDrawIndexedInfoEXT *_draw = (const void*)(_pDrawInfo); \
262
(_i) < (_num_draws); \
263
(_i)++, (_draw) = (const VkMultiDrawIndexedInfoEXT*)((const uint8_t*)(_draw) + (_stride)))
265
/* iterate over a sequence of multidraws for VK_EXT_multi_draw extension */
266
/* 'i' must be explicitly declared */
267
#define vk_foreach_multi_draw(_draw, _i, _pDrawInfo, _num_draws, _stride) \
268
for (const VkMultiDrawInfoEXT *_draw = (const void*)(_pDrawInfo); \
269
(_i) < (_num_draws); \
270
(_i)++, (_draw) = (const VkMultiDrawInfoEXT*)((const uint8_t*)(_draw) + (_stride)))
273
struct nir_spirv_specialization;
275
struct nir_spirv_specialization*
276
vk_spec_info_to_nir_spirv(const VkSpecializationInfo *spec_info,
277
uint32_t *out_num_spec_entries);
279
#define STACK_ARRAY_SIZE 8
282
#define STACK_ARRAY_ZERO_INIT {}
284
#define STACK_ARRAY_ZERO_INIT {0}
287
#define STACK_ARRAY(type, name, size) \
288
type _stack_##name[STACK_ARRAY_SIZE] = STACK_ARRAY_ZERO_INIT; \
290
((size) <= STACK_ARRAY_SIZE ? _stack_##name : (type *)malloc((size) * sizeof(type)))
292
#define STACK_ARRAY_FINISH(name) \
293
if (name != _stack_##name) free(name)
299
#endif /* VK_UTIL_H */