parent
68bea8a225
commit
ee79b4c195
@ -0,0 +1,2 @@ |
||||
*.o |
||||
test3 |
@ -0,0 +1,22 @@ |
||||
CC = gcc
|
||||
LD = gcc
|
||||
CFLAGS = -Wall -Wextra -pedantic -std=c11 -g -fPIC
|
||||
# link kompute as a static library and the rest as dynamic
|
||||
STATIC_LIBS =
|
||||
DYNAMIC_LIBS = -lvulkan
|
||||
LDFLAGS = -L/usr/local/lib \
|
||||
-Wl,-Bstatic ${STATIC_LIBS} \
|
||||
-Wl,-Bdynamic ${DYNAMIC_LIBS} \
|
||||
-Wl,--as-needed
|
||||
|
||||
test3: main.o vk_result_to_str.o |
||||
$(LD) main.o vk_result_to_str.o -o test3 ${LDFLAGS}
|
||||
|
||||
vk_result_to_str.o: vk_result_to_str.c |
||||
$(CC) ${CFLAGS} -c vk_result_to_str.c
|
||||
|
||||
main.o: main.c |
||||
$(CC) ${CFLAGS} -c main.c
|
||||
|
||||
clean: |
||||
rm -f test3 main.o vk_result_to_str.o
|
@ -0,0 +1 @@ |
||||
Trying to implement test2 with just vulkan and in C |
@ -0,0 +1,328 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <stddef.h> |
||||
#include <stdarg.h> |
||||
#include <string.h> |
||||
#include <errno.h> |
||||
|
||||
#include <vulkan/vulkan.h> |
||||
|
||||
// check for half precision floating point support, for x86 this is equivalent to
|
||||
// checking for SSE2
|
||||
#define SUPPORTS_NATIVE_FP16 (__x86_64__ == 1 && __SSE2__ == 1) |
||||
// print debug messages
|
||||
#define DEBUG 1 |
||||
#define VERBOSE 0 |
||||
|
||||
// define half precision floating point
|
||||
#if SUPPORTS_NATIVE_FP16 |
||||
// extension is needed due to -pedantic
|
||||
__extension__ typedef _Float16 half; |
||||
#endif |
||||
|
||||
const char *vk_validation_layer[] = {"VK_LAYER_KHRONOS_validation"}; |
||||
const uint32_t vk_validation_layer_no = 1; |
||||
|
||||
// FIXME: including vulkan/vk_enum_string_helper.h does not compile
|
||||
extern const char *vk_Result_to_str(VkResult input); |
||||
|
||||
// like printf but on stderr
|
||||
int err(const char *fmt, ...) |
||||
{ |
||||
va_list ap; |
||||
va_start(ap, fmt); |
||||
int ret = vfprintf(stderr, fmt, ap); |
||||
va_end(ap); |
||||
return ret; |
||||
} |
||||
|
||||
// print out all the instance extensions
|
||||
// NOTE: these are different from device and shader extensions
|
||||
int vk_enumerate_instance_extensions(void) |
||||
{ |
||||
uint32_t ex_no = 0; |
||||
#if VERBOSE > 0 |
||||
vkEnumerateInstanceExtensionProperties(NULL, &ex_no, NULL); |
||||
VkExtensionProperties *ex_arr = |
||||
malloc(sizeof(VkExtensionProperties) * ex_no); |
||||
if (ex_arr == NULL) { |
||||
err("ERROR: in %s: %s\n", __func__, strerror(errno)); |
||||
return -1; |
||||
} |
||||
vkEnumerateInstanceExtensionProperties(NULL, &ex_no, ex_arr); |
||||
printf("Available Properties: \n"); |
||||
for (uint32_t i = 0; i < ex_no; i++) { |
||||
printf("\t%s\n", ex_arr[i].extensionName); |
||||
} |
||||
free(ex_arr); |
||||
#endif |
||||
return ex_no; |
||||
} |
||||
|
||||
// on debug check for support of validation layers and activate one, a validation
|
||||
// layer is useful to do more error checking at runtime like ckecking for invalid
|
||||
// arguments, validation layers are available only if vulkan-sdk is installed
|
||||
// (vulkan-devel on arch)
|
||||
int vk_activate_validation_layer(VkInstanceCreateInfo *cinfo) |
||||
{ |
||||
uint32_t prop_no = 0; |
||||
#if DEBUG > 0 |
||||
vkEnumerateInstanceLayerProperties(&prop_no, NULL); |
||||
|
||||
VkLayerProperties *prop_arr = malloc(sizeof(VkLayerProperties) * prop_no); |
||||
if (prop_arr == NULL) { |
||||
err("ERROR: in %s: %s\n", __func__, strerror(errno)); |
||||
return -1; |
||||
} |
||||
vkEnumerateInstanceLayerProperties(&prop_no, prop_arr); |
||||
|
||||
for (uint32_t i = 0; i < prop_no; i++) { |
||||
if (strcmp(prop_arr[i].layerName, vk_validation_layer[0]) == 0) { |
||||
cinfo->enabledLayerCount = vk_validation_layer_no; |
||||
cinfo->ppEnabledLayerNames = vk_validation_layer; |
||||
free(prop_arr); |
||||
return 0; |
||||
} |
||||
} |
||||
free(prop_arr); |
||||
return 1; |
||||
#endif |
||||
return 0; |
||||
} |
||||
|
||||
VkInstance vk_init(void) |
||||
{ |
||||
// create a vulkan instance and fill it with the application data
|
||||
VkResult res; |
||||
VkInstance vk_instance = VK_NULL_HANDLE; |
||||
|
||||
VkApplicationInfo vk_appinfo = { |
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, |
||||
.pNext = NULL, |
||||
.pApplicationName = __FILE__, |
||||
.applicationVersion = VK_MAKE_VERSION(0, 1, 0), |
||||
.pEngineName = "no engine", |
||||
.engineVersion = VK_MAKE_VERSION(0, 0, 0), |
||||
.apiVersion = VK_API_VERSION_1_3, |
||||
}; |
||||
|
||||
vk_enumerate_instance_extensions(); |
||||
|
||||
// TODO: check for extension availability
|
||||
// TODO: does the lifetime of VkInstanceCreateInfo has to be the same as the
|
||||
// lifetime of VkInstance?
|
||||
const char *vk_instance_extensions[] = { |
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, |
||||
}; |
||||
const uint32_t vk_instance_extensions_no = |
||||
(uint32_t)(sizeof(vk_instance_extensions) / sizeof(char *)); |
||||
|
||||
VkInstanceCreateInfo vk_instanceinfo = { |
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, |
||||
.pApplicationInfo = &vk_appinfo, |
||||
.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, |
||||
.enabledExtensionCount = vk_instance_extensions_no, |
||||
.ppEnabledExtensionNames = vk_instance_extensions, |
||||
.enabledLayerCount = 0, |
||||
}; |
||||
|
||||
int e = 0; |
||||
if ((e = vk_activate_validation_layer(&vk_instanceinfo))) { |
||||
err("Could not activate validation layers%s\n", |
||||
e > 0 ? ": No validation layers found" : ""); |
||||
} |
||||
|
||||
res = vkCreateInstance(&vk_instanceinfo, NULL, &vk_instance); |
||||
if (res != VK_SUCCESS) { |
||||
err("ERROR: Could not create vulkan instance %s", |
||||
vk_Result_to_str(res)); |
||||
return VK_NULL_HANDLE; |
||||
} else { |
||||
#if VERBOSE > 0 |
||||
printf("Created vulkan instance\n"); |
||||
#endif |
||||
} |
||||
return vk_instance; |
||||
} |
||||
|
||||
void vk_destroy(VkInstance vk_instance) |
||||
{ |
||||
// ...
|
||||
vkDestroyInstance(vk_instance, NULL); |
||||
} |
||||
|
||||
VkPhysicalDevice vk_physical_device_get(VkInstance vk_instance) |
||||
{ |
||||
VkPhysicalDevice vk_phydev = VK_NULL_HANDLE; |
||||
|
||||
uint32_t vk_phydevs_no = 0; |
||||
VkPhysicalDevice *vk_phydevs; |
||||
vkEnumeratePhysicalDevices(vk_instance, &vk_phydevs_no, NULL); |
||||
|
||||
if (vk_phydevs_no == 0) { |
||||
return vk_phydev; |
||||
} |
||||
|
||||
vk_phydevs = malloc(sizeof(VkPhysicalDevice) * vk_phydevs_no); |
||||
if (vk_phydevs == NULL) { |
||||
err("ERROR: in %s: %s\n", __func__, strerror(errno)); |
||||
return NULL; |
||||
} |
||||
|
||||
vkEnumeratePhysicalDevices(vk_instance, &vk_phydevs_no, vk_phydevs); |
||||
|
||||
printf("Available Physical Devices: \n"); |
||||
for (uint32_t i = 0; i < vk_phydevs_no; i++) { |
||||
VkPhysicalDevice device = vk_phydevs[i]; |
||||
VkPhysicalDeviceProperties device_properties; |
||||
VkPhysicalDeviceFeatures device_features; |
||||
|
||||
vkGetPhysicalDeviceProperties(device, &device_properties); |
||||
vkGetPhysicalDeviceFeatures(device, &device_features); |
||||
|
||||
printf( |
||||
"\tDevice %d: %s, Discrete: %s\n", |
||||
i, |
||||
device_properties.deviceName, |
||||
device_properties.deviceType == |
||||
VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU |
||||
? "true" |
||||
: "false" |
||||
); |
||||
} |
||||
|
||||
// TODO: find the most suitable physical device, but for now every vulkan
|
||||
// device has to be compatible with compute shaders
|
||||
vk_phydev = vk_phydevs[0]; |
||||
|
||||
free(vk_phydevs); |
||||
return vk_phydev; |
||||
} |
||||
|
||||
void vk_physical_device_destroy(VkPhysicalDevice vk_phydev) |
||||
{ |
||||
if (vk_phydev != VK_NULL_HANDLE) { |
||||
// ...
|
||||
} |
||||
} |
||||
|
||||
// return the index of the first queue family that supports compute on the device,
|
||||
// returns a negative index on error
|
||||
int vk_device_compute_queue_index(VkPhysicalDevice vk_phydev) |
||||
{ |
||||
uint32_t vk_qfamilies_no = 0; |
||||
VkQueueFamilyProperties *vk_qfamilies; |
||||
int supports = -1; |
||||
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(vk_phydev, &vk_qfamilies_no, NULL); |
||||
|
||||
vk_qfamilies = malloc(sizeof(VkQueueFamilyProperties) * vk_qfamilies_no); |
||||
if (vk_qfamilies == NULL) { |
||||
err("ERROR: in %s: %s\n", __func__, strerror(errno)); |
||||
return -1; |
||||
} |
||||
|
||||
vkGetPhysicalDeviceQueueFamilyProperties( |
||||
vk_phydev, &vk_qfamilies_no, vk_qfamilies |
||||
); |
||||
|
||||
for (uint32_t i = 0; i < vk_qfamilies_no; i++) { |
||||
if (vk_qfamilies[i].queueFlags & VK_QUEUE_COMPUTE_BIT) { |
||||
supports = i; |
||||
} |
||||
} |
||||
|
||||
free(vk_qfamilies); |
||||
return supports; |
||||
} |
||||
|
||||
VkDevice vk_logical_device_create(VkPhysicalDevice vk_phydev, int qfamily_idx) |
||||
{ |
||||
VkResult res; |
||||
VkDevice vk_logdev = VK_NULL_HANDLE; |
||||
float vk_queue_priority = 1.0f; |
||||
|
||||
// specify which command queues to use for the physical device
|
||||
VkDeviceQueueCreateInfo vk_queueinfo = { |
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, |
||||
.pNext = NULL, |
||||
.flags = 0, |
||||
.queueFamilyIndex = qfamily_idx, |
||||
.queueCount = 1, |
||||
.pQueuePriorities = &vk_queue_priority, |
||||
}; |
||||
|
||||
// specify which device features to use
|
||||
// TODO: this
|
||||
VkPhysicalDeviceFeatures vk_phydev_features = {0}; |
||||
|
||||
// actually create the logical device
|
||||
// TODO: figure out what device extensions are
|
||||
// FIXME: here validation layers are ignored but it is still better to define
|
||||
// them for compatibility
|
||||
VkDeviceCreateInfo vk_createinfo = { |
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, |
||||
.pQueueCreateInfos = &vk_queueinfo, |
||||
.queueCreateInfoCount = 1, |
||||
.pEnabledFeatures = &vk_phydev_features, |
||||
.ppEnabledExtensionNames = NULL, |
||||
.enabledExtensionCount = 0, |
||||
.ppEnabledLayerNames = NULL, |
||||
.enabledLayerCount = 0, |
||||
}; |
||||
|
||||
res = vkCreateDevice(vk_phydev, &vk_createinfo, NULL, &vk_logdev); |
||||
if (res != VK_SUCCESS) { |
||||
err("ERROR: Could not create vulkan logical device %s", |
||||
vk_Result_to_str(res)); |
||||
return VK_NULL_HANDLE; |
||||
} else { |
||||
#if VERBOSE > 0 |
||||
printf("Created vulkan logical device\n"); |
||||
#endif |
||||
} |
||||
|
||||
return vk_logdev; |
||||
} |
||||
|
||||
void vk_logical_device_destroy(VkDevice vk_logdev) |
||||
{ |
||||
vkDestroyDevice(vk_logdev, NULL); |
||||
} |
||||
|
||||
VkQueue vk_queue_get(VkDevice vk_logdev, int qfamily_idx) |
||||
{ |
||||
VkQueue vk_queue = VK_NULL_HANDLE; |
||||
vkGetDeviceQueue(vk_logdev, qfamily_idx, 0, &vk_queue); |
||||
return vk_queue; |
||||
} |
||||
|
||||
int main(void) |
||||
{ |
||||
#if VERBOSE > 0 |
||||
if (SUPPORTS_NATIVE_FP16) { |
||||
printf("Processor supports half precision floating point\n"); |
||||
} else { |
||||
printf("Processor doesn't support half precision floating point\n"); |
||||
return EXIT_FAILURE; |
||||
} |
||||
#endif |
||||
|
||||
VkInstance vk_instance = vk_init(); |
||||
if (vk_instance == VK_NULL_HANDLE) { |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
VkPhysicalDevice vk_phydev = vk_physical_device_get(vk_instance); |
||||
int qfamily_idx = vk_device_compute_queue_index(vk_phydev); |
||||
if (qfamily_idx < 0) { |
||||
err("The device does not support compute queues\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
VkDevice vk_logdev = vk_logical_device_create(vk_phydev, qfamily_idx); |
||||
|
||||
vk_logical_device_destroy(vk_logdev); |
||||
vk_physical_device_destroy(vk_phydev); |
||||
vk_destroy(vk_instance); |
||||
|
||||
return EXIT_SUCCESS; |
||||
} |
@ -0,0 +1,3 @@ |
||||
__pycache__ |
||||
out |
||||
vk.xml |
@ -0,0 +1,6 @@ |
||||
out/vk_enum_to_str.c: vk.xml |
||||
python gen_enum_to_str.py --beta false --xml vk.xml --outdir out
|
||||
|
||||
vk.xml: |
||||
wget -O vk.xml https://raw.githubusercontent.com/KhronosGroup/Vulkan-Docs/main/xml/vk.xml
|
||||
|
@ -0,0 +1,573 @@ |
||||
# Copyright © 2017 Intel Corporation |
||||
|
||||
# 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 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. |
||||
|
||||
"""Create enum to string functions for vulkan using vk.xml.""" |
||||
|
||||
import argparse |
||||
import functools |
||||
import os |
||||
import re |
||||
import textwrap |
||||
import xml.etree.ElementTree as et |
||||
|
||||
from mako.template import Template |
||||
from vk_extensions import Extension, filter_api, get_all_required |
||||
|
||||
COPYRIGHT = textwrap.dedent(u"""\ |
||||
* Copyright © 2017 Intel Corporation |
||||
* |
||||
* 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 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.""") |
||||
|
||||
C_TEMPLATE = Template(textwrap.dedent(u"""\ |
||||
/* Autogenerated file -- do not edit |
||||
* generated by ${file} |
||||
* |
||||
${copyright} |
||||
*/ |
||||
|
||||
#include <string.h> |
||||
#include <vulkan/vulkan_core.h> |
||||
#include <vulkan/vk_android_native_buffer.h> |
||||
#include <vulkan/vk_layer.h> |
||||
#include "util/macros.h" |
||||
#include "vk_enum_to_str.h" |
||||
|
||||
% for enum in enums: |
||||
|
||||
% if enum.guard: |
||||
#ifdef ${enum.guard} |
||||
% endif |
||||
const char * |
||||
vk_${enum.name[2:]}_to_str(${enum.name} input) |
||||
{ |
||||
switch((int64_t)input) { |
||||
% for v in sorted(enum.values.keys()): |
||||
case ${v}: |
||||
return "${enum.values[v]}"; |
||||
% endfor |
||||
case ${enum.max_enum_name}: return "${enum.max_enum_name}"; |
||||
default: |
||||
return "Unknown ${enum.name} value."; |
||||
} |
||||
} |
||||
|
||||
% if enum.guard: |
||||
#endif |
||||
% endif |
||||
%endfor |
||||
|
||||
% for enum in bitmasks: |
||||
|
||||
% if enum.guard: |
||||
#ifdef ${enum.guard} |
||||
% endif |
||||
const char * |
||||
vk_${enum.name[2:]}_to_str(${enum.name} input) |
||||
{ |
||||
switch((int64_t)input) { |
||||
% for v in sorted(enum.values.keys()): |
||||
case ${v}: |
||||
return "${enum.values[v]}"; |
||||
% endfor |
||||
default: |
||||
return "Unknown ${enum.name} value."; |
||||
} |
||||
} |
||||
|
||||
% if enum.guard: |
||||
#endif |
||||
% endif |
||||
%endfor |
||||
|
||||
size_t vk_structure_type_size(const struct VkBaseInStructure *item) |
||||
{ |
||||
switch((int)item->sType) { |
||||
% for struct in structs: |
||||
% if struct.extension is not None and struct.extension.define is not None: |
||||
#ifdef ${struct.extension.define} |
||||
case ${struct.stype}: return sizeof(${struct.name}); |
||||
#endif |
||||
% else: |
||||
case ${struct.stype}: return sizeof(${struct.name}); |
||||
% endif |
||||
%endfor |
||||
case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO: return sizeof(VkLayerInstanceCreateInfo); |
||||
case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO: return sizeof(VkLayerDeviceCreateInfo); |
||||
default: |
||||
unreachable("Undefined struct type."); |
||||
} |
||||
} |
||||
|
||||
const char * |
||||
vk_ObjectType_to_ObjectName(VkObjectType type) |
||||
{ |
||||
switch((int)type) { |
||||
% for object_type in sorted(object_types[0].enum_to_name.keys()): |
||||
case ${object_type}: |
||||
return "${object_types[0].enum_to_name[object_type]}"; |
||||
% endfor |
||||
default: |
||||
return "Unknown VkObjectType value."; |
||||
} |
||||
} |
||||
""")) |
||||
|
||||
H_TEMPLATE = Template(textwrap.dedent(u"""\ |
||||
/* Autogenerated file -- do not edit |
||||
* generated by ${file} |
||||
* |
||||
${copyright} |
||||
*/ |
||||
|
||||
#ifndef MESA_VK_ENUM_TO_STR_H |
||||
#define MESA_VK_ENUM_TO_STR_H |
||||
|
||||
#include <vulkan/vulkan.h> |
||||
#include <vulkan/vk_android_native_buffer.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
% for enum in enums: |
||||
% if enum.guard: |
||||
#ifdef ${enum.guard} |
||||
% endif |
||||
const char * vk_${enum.name[2:]}_to_str(${enum.name} input); |
||||
% if enum.guard: |
||||
#endif |
||||
% endif |
||||
% endfor |
||||
|
||||
% for enum in bitmasks: |
||||
% if enum.guard: |
||||
#ifdef ${enum.guard} |
||||
% endif |
||||
const char * vk_${enum.name[2:]}_to_str(${enum.name} input); |
||||
% if enum.guard: |
||||
#endif |
||||
% endif |
||||
% endfor |
||||
|
||||
size_t vk_structure_type_size(const struct VkBaseInStructure *item); |
||||
|
||||
const char * vk_ObjectType_to_ObjectName(VkObjectType type); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#endif""")) |
||||
|
||||
|
||||
H_DEFINE_TEMPLATE = Template(textwrap.dedent(u"""\ |
||||
/* Autogenerated file -- do not edit |
||||
* generated by ${file} |
||||
* |
||||
${copyright} |
||||
*/ |
||||
|
||||
#ifndef MESA_VK_ENUM_DEFINES_H |
||||
#define MESA_VK_ENUM_DEFINES_H |
||||
|
||||
#include <vulkan/vulkan_core.h> |
||||
#include <vulkan/vk_android_native_buffer.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
% for ext in extensions: |
||||
#define _${ext.name}_number (${ext.number}) |
||||
% endfor |
||||
|
||||
% for enum in bitmasks: |
||||
% if enum.bitwidth > 32: |
||||
<% continue %> |
||||
% endif |
||||
% if enum.guard: |
||||
#ifdef ${enum.guard} |
||||
% endif |
||||
#define ${enum.all_bits_name()} ${hex(enum.all_bits_value())}u |
||||
% if enum.guard: |
||||
#endif |
||||
% endif |
||||
% endfor |
||||
|
||||
% for enum in bitmasks: |
||||
% if enum.bitwidth < 64: |
||||
<% continue %> |
||||
% endif |
||||
/* Redefine bitmask values of ${enum.name} */ |
||||
% if enum.guard: |
||||
#ifdef ${enum.guard} |
||||
% endif |
||||
% for n, v in enum.name_to_value.items(): |
||||
#define ${n} (${hex(v)}ULL) |
||||
% endfor |
||||
% if enum.guard: |
||||
#endif |
||||
% endif |
||||
% endfor |
||||
|
||||
static inline VkFormatFeatureFlags |
||||
vk_format_features2_to_features(VkFormatFeatureFlags2 features2) |
||||
{ |
||||
return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS; |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#endif""")) |
||||
|
||||
|
||||
class NamedFactory(object): |
||||
"""Factory for creating enums.""" |
||||
|
||||
def __init__(self, type_): |
||||
self.registry = {} |
||||
self.type = type_ |
||||
|
||||
def __call__(self, name, **kwargs): |
||||
try: |
||||
return self.registry[name] |
||||
except KeyError: |
||||
n = self.registry[name] = self.type(name, **kwargs) |
||||
return n |
||||
|
||||
def get(self, name): |
||||
return self.registry.get(name) |
||||
|
||||
|
||||
class VkExtension(object): |
||||
"""Simple struct-like class representing extensions""" |
||||
|
||||
def __init__(self, name, number=None, define=None): |
||||
self.name = name |
||||
self.number = number |
||||
self.define = define |
||||
|
||||
|
||||
def CamelCase_to_SHOUT_CASE(s): |
||||
return (s[:1] + re.sub(r'(?<![A-Z])([A-Z])', r'_\1', s[1:])).upper() |
||||
|
||||
def compute_max_enum_name(s): |
||||
if s == "VkSwapchainImageUsageFlagBitsANDROID": |
||||
return "VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM" |
||||
max_enum_name = CamelCase_to_SHOUT_CASE(s) |
||||
last_prefix = max_enum_name.rsplit('_', 1)[-1] |
||||
# Those special prefixes need to be always at the end |
||||
if last_prefix in ['AMD', 'EXT', 'INTEL', 'KHR', 'NV', 'LUNARG', 'QCOM', 'MSFT'] : |
||||
max_enum_name = "_".join(max_enum_name.split('_')[:-1]) |
||||
max_enum_name = max_enum_name + "_MAX_ENUM_" + last_prefix |
||||
else: |
||||
max_enum_name = max_enum_name + "_MAX_ENUM" |
||||
|
||||
return max_enum_name |
||||
|
||||
class VkEnum(object): |
||||
"""Simple struct-like class representing a single Vulkan Enum.""" |
||||
|
||||
def __init__(self, name, bitwidth=32, values=None): |
||||
self.name = name |
||||
self.max_enum_name = compute_max_enum_name(name) |
||||
self.bitwidth = bitwidth |
||||
self.extension = None |
||||
# Maps numbers to names |
||||
self.values = values or dict() |
||||
self.name_to_value = dict() |
||||
self.guard = None |
||||
self.name_to_alias_list = {} |
||||
|
||||
def all_bits_name(self): |
||||
assert self.name.startswith('Vk') |
||||
assert re.search(r'FlagBits[A-Z]*$', self.name) |
||||
|
||||
return 'VK_ALL_' + CamelCase_to_SHOUT_CASE(self.name[2:]) |
||||
|
||||
def all_bits_value(self): |
||||
return functools.reduce(lambda a,b: a | b, self.values.keys(), 0) |
||||
|
||||
def add_value(self, name, value=None, |
||||
extnum=None, offset=None, alias=None, |
||||
error=False): |
||||
if alias is not None: |
||||
assert value is None and offset is None |
||||
if alias not in self.name_to_value: |
||||
# We don't have this alias yet. Just record the alias and |
||||
# we'll deal with it later. |
||||
alias_list = self.name_to_alias_list.setdefault(alias, []) |
||||
alias_list.append(name); |
||||
return |
||||
|
||||
# Use the value from the alias |
||||
value = self.name_to_value[alias] |
||||
|
||||
assert value is not None or extnum is not None |
||||
if value is None: |
||||
value = 1000000000 + (extnum - 1) * 1000 + offset |
||||
if error: |
||||
value = -value |
||||
|
||||
self.name_to_value[name] = value |
||||
if value not in self.values: |
||||
self.values[value] = name |
||||
elif len(self.values[value]) > len(name): |
||||
self.values[value] = name |
||||
|
||||
# Now that the value has been fully added, resolve aliases, if any. |
||||
if name in self.name_to_alias_list: |
||||
for alias in self.name_to_alias_list[name]: |
||||
self.add_value(alias, value) |
||||
del self.name_to_alias_list[name] |
||||
|
||||
def add_value_from_xml(self, elem, extension=None): |
||||
self.extension = extension |
||||
if 'value' in elem.attrib: |
||||
self.add_value(elem.attrib['name'], |
||||
value=int(elem.attrib['value'], base=0)) |
||||
elif 'bitpos' in elem.attrib: |
||||
self.add_value(elem.attrib['name'], |
||||
value=(1 << int(elem.attrib['bitpos'], base=0))) |
||||
elif 'alias' in elem.attrib: |
||||
self.add_value(elem.attrib['name'], alias=elem.attrib['alias']) |
||||
else: |
||||
error = 'dir' in elem.attrib and elem.attrib['dir'] == '-' |
||||
if 'extnumber' in elem.attrib: |
||||
extnum = int(elem.attrib['extnumber']) |
||||
else: |
||||
extnum = extension.number |
||||
self.add_value(elem.attrib['name'], |
||||
extnum=extnum, |
||||
offset=int(elem.attrib['offset']), |
||||
error=error) |
||||
|
||||
def set_guard(self, g): |
||||
self.guard = g |
||||
|
||||
|
||||
class VkChainStruct(object): |
||||
"""Simple struct-like class representing a single Vulkan struct identified with a VkStructureType""" |
||||
def __init__(self, name, stype): |
||||
self.name = name |
||||
self.stype = stype |
||||
self.extension = None |
||||
|
||||
|
||||
def struct_get_stype(xml_node): |
||||
for member in xml_node.findall('./member'): |
||||
name = member.findall('./name') |
||||
if len(name) > 0 and name[0].text == "sType": |
||||
return member.get('values') |
||||
return None |
||||
|
||||
class VkObjectType(object): |
||||
"""Simple struct-like class representing a single Vulkan object type""" |
||||
def __init__(self, name): |
||||
self.name = name |
||||
self.enum_to_name = dict() |
||||
|
||||
|
||||
def parse_xml(enum_factory, ext_factory, struct_factory, bitmask_factory, |
||||
obj_type_factory, filename, beta): |
||||
"""Parse the XML file. Accumulate results into the factories. |
||||
|
||||
This parser is a memory efficient iterative XML parser that returns a list |
||||
of VkEnum objects. |
||||
""" |
||||
|
||||
xml = et.parse(filename) |
||||
api = 'vulkan' |
||||
|
||||
required_types = get_all_required(xml, 'type', api, beta) |
||||
|
||||
for enum_type in xml.findall('./enums[@type="enum"]'): |
||||
if not filter_api(enum_type, api): |
||||
continue |
||||
|
||||
type_name = enum_type.attrib['name'] |
||||
if not type_name in required_types: |
||||
continue |
||||
|
||||
enum = enum_factory(type_name) |
||||
for value in enum_type.findall('./enum'): |
||||
if filter_api(value, api): |
||||
enum.add_value_from_xml(value) |
||||
|
||||
# For bitmask we only add the Enum selected for convenience. |
||||
for enum_type in xml.findall('./enums[@type="bitmask"]'): |
||||
if not filter_api(enum_type, api): |
||||
continue |
||||
|
||||
type_name = enum_type.attrib['name'] |
||||
if not type_name in required_types: |
||||
continue |
||||
|
||||
bitwidth = int(enum_type.attrib.get('bitwidth', 32)) |
||||
enum = bitmask_factory(type_name, bitwidth=bitwidth) |
||||
for value in enum_type.findall('./enum'): |
||||
if filter_api(value, api): |
||||
enum.add_value_from_xml(value) |
||||
|
||||
for feature in xml.findall('./feature'): |
||||
if not api in feature.attrib['api'].split(','): |
||||
continue |
||||
|
||||
for value in feature.findall('./require/enum[@extends]'): |
||||
extends = value.attrib['extends'] |
||||
enum = enum_factory.get(extends) |
||||
if enum is not None: |
||||
enum.add_value_from_xml(value) |
||||
enum = bitmask_factory.get(extends) |
||||
if enum is not None: |
||||
enum.add_value_from_xml(value) |
||||
|
||||
for struct_type in xml.findall('./types/type[@category="struct"]'): |
||||
if not filter_api(struct_type, api): |
||||
continue |
||||
|
||||
name = struct_type.attrib['name'] |
||||
if name not in required_types: |
||||
continue |
||||
|
||||
stype = struct_get_stype(struct_type) |
||||
if stype is not None: |
||||
struct_factory(name, stype=stype) |
||||
|
||||
platform_define = {} |
||||
for platform in xml.findall('./platforms/platform'): |
||||
name = platform.attrib['name'] |
||||
define = platform.attrib['protect'] |
||||
platform_define[name] = define |
||||
|
||||
for ext_elem in xml.findall('./extensions/extension'): |
||||
ext = Extension.from_xml(ext_elem) |
||||
if api not in ext.supported: |
||||
continue |
||||
|
||||
define = platform_define.get(ext.platform, None) |
||||
extension = ext_factory(ext.name, number=ext.number, define=define) |
||||
|
||||
for req_elem in ext_elem.findall('./require'): |
||||
if not filter_api(req_elem, api): |
||||
continue |
||||
|
||||
for value in req_elem.findall('./enum[@extends]'): |
||||
extends = value.attrib['extends'] |
||||
enum = enum_factory.get(extends) |
||||
if enum is not None: |
||||
enum.add_value_from_xml(value, extension) |
||||
enum = bitmask_factory.get(extends) |
||||
if enum is not None: |
||||
enum.add_value_from_xml(value, extension) |
||||
|
||||
for t in req_elem.findall('./type'): |
||||
struct = struct_factory.get(t.attrib['name']) |
||||
if struct is not None: |
||||
struct.extension = extension |
||||
|
||||
if define: |
||||
for value in ext_elem.findall('./require/type[@name]'): |
||||
enum = enum_factory.get(value.attrib['name']) |
||||
if enum is not None: |
||||
enum.set_guard(define) |
||||
enum = bitmask_factory.get(value.attrib['name']) |
||||
if enum is not None: |
||||
enum.set_guard(define) |
||||
|
||||
obj_type_enum = enum_factory.get("VkObjectType") |
||||
obj_types = obj_type_factory("VkObjectType") |
||||
for object_type in xml.findall('./types/type[@category="handle"]'): |
||||
for object_name in object_type.findall('./name'): |
||||
# Convert to int to avoid undefined enums |
||||
enum = object_type.attrib['objtypeenum'] |
||||
|
||||
# Annoyingly, object types are hard to filter by API so just |
||||
# look for whether or not we can find the enum name in the |
||||
# VkObjectType enum. |
||||
if enum not in obj_type_enum.name_to_value: |
||||
continue |
||||
|
||||
enum_val = obj_type_enum.name_to_value[enum] |
||||
obj_types.enum_to_name[enum_val] = object_name.text |
||||
|
||||
|
||||
def main(): |
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument('--beta', required=True, help='Enable beta extensions.') |
||||
parser.add_argument('--xml', required=True, |
||||
help='Vulkan API XML files', |
||||
action='append', |
||||
dest='xml_files') |
||||
parser.add_argument('--outdir', |
||||
help='Directory to put the generated files in', |
||||
required=True) |
||||
|
||||
args = parser.parse_args() |
||||
|
||||
enum_factory = NamedFactory(VkEnum) |
||||
ext_factory = NamedFactory(VkExtension) |
||||
struct_factory = NamedFactory(VkChainStruct) |
||||
obj_type_factory = NamedFactory(VkObjectType) |
||||
bitmask_factory = NamedFactory(VkEnum) |
||||
|
||||
for filename in args.xml_files: |
||||
parse_xml(enum_factory, ext_factory, struct_factory, bitmask_factory, |
||||
obj_type_factory, filename, args.beta) |
||||
enums = sorted(enum_factory.registry.values(), key=lambda e: e.name) |
||||
extensions = sorted(ext_factory.registry.values(), key=lambda e: e.name) |
||||
structs = sorted(struct_factory.registry.values(), key=lambda e: e.name) |
||||
bitmasks = sorted(bitmask_factory.registry.values(), key=lambda e: e.name) |
||||
object_types = sorted(obj_type_factory.registry.values(), key=lambda e: e.name) |
||||
|
||||
for template, file_ in [(C_TEMPLATE, os.path.join(args.outdir, 'vk_enum_to_str.c')), |
||||
(H_TEMPLATE, os.path.join(args.outdir, 'vk_enum_to_str.h')), |
||||
(H_DEFINE_TEMPLATE, os.path.join(args.outdir, 'vk_enum_defines.h'))]: |
||||
with open(file_, 'w', encoding='utf-8') as f: |
||||
f.write(template.render( |
||||
file=os.path.basename(__file__), |
||||
enums=enums, |
||||
extensions=extensions, |
||||
structs=structs, |
||||
bitmasks=bitmasks, |
||||
object_types=object_types, |
||||
copyright=COPYRIGHT)) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main() |
@ -0,0 +1,3 @@ |
||||
#!/bin/sh |
||||
|
||||
gcc -msse3 -dM -E - < /dev/null | grep -E "SSE|AVX" | sort |
@ -0,0 +1,356 @@ |
||||
import copy |
||||
import re |
||||
import xml.etree.ElementTree as et |
||||
|
||||
def get_api_list(s): |
||||
apis = [] |
||||
for a in s.split(','): |
||||
if a == 'disabled': |
||||
continue |
||||
assert a in ('vulkan', 'vulkansc') |
||||
apis.append(a) |
||||
return apis |
||||
|
||||
class Extension: |
||||
def __init__(self, name, number, ext_version): |
||||
self.name = name |
||||
self.type = None |
||||
self.number = number |
||||
self.platform = None |
||||
self.provisional = False |
||||
self.ext_version = int(ext_version) |
||||
self.supported = [] |
||||
|
||||
def from_xml(ext_elem): |
||||
name = ext_elem.attrib['name'] |
||||
number = int(ext_elem.attrib['number']) |
||||
supported = get_api_list(ext_elem.attrib['supported']) |
||||
if name == 'VK_ANDROID_native_buffer': |
||||
assert not supported |
||||
supported = ['vulkan'] |
||||
|
||||
if not supported: |
||||
return Extension(name, number, 0) |
||||
|
||||
version = None |
||||
for enum_elem in ext_elem.findall('.require/enum'): |
||||
if enum_elem.attrib['name'].endswith('_SPEC_VERSION'): |
||||
# Skip alias SPEC_VERSIONs |
||||
if 'value' in enum_elem.attrib: |
||||
assert version is None |
||||
version = int(enum_elem.attrib['value']) |
||||
|
||||
assert version is not None |
||||
ext = Extension(name, number, version) |
||||
ext.type = ext_elem.attrib['type'] |
||||
ext.platform = ext_elem.attrib.get('platform', None) |
||||
ext.provisional = ext_elem.attrib.get('provisional', False) |
||||
ext.supported = supported |
||||
|
||||
return ext |
||||
|
||||
def c_android_condition(self): |
||||
# if it's an EXT or vendor extension, it's allowed |
||||
if not self.name.startswith(ANDROID_EXTENSION_WHITELIST_PREFIXES): |
||||
return 'true' |
||||
|
||||
allowed_version = ALLOWED_ANDROID_VERSION.get(self.name, None) |
||||
if allowed_version is None: |
||||
return 'false' |
||||
|
||||
return 'ANDROID_API_LEVEL >= %d' % (allowed_version) |
||||
|
||||
class ApiVersion: |
||||
def __init__(self, version): |
||||
self.version = version |
||||
|
||||
class VkVersion: |
||||
def __init__(self, string): |
||||
split = string.split('.') |
||||
self.major = int(split[0]) |
||||
self.minor = int(split[1]) |
||||
if len(split) > 2: |
||||
assert len(split) == 3 |
||||
self.patch = int(split[2]) |
||||
else: |
||||
self.patch = None |
||||
|
||||
# Sanity check. The range bits are required by the definition of the |
||||
# VK_MAKE_VERSION macro |
||||
assert self.major < 1024 and self.minor < 1024 |
||||
assert self.patch is None or self.patch < 4096 |
||||
assert str(self) == string |
||||
|
||||
def __str__(self): |
||||
ver_list = [str(self.major), str(self.minor)] |
||||
if self.patch is not None: |
||||
ver_list.append(str(self.patch)) |
||||
return '.'.join(ver_list) |
||||
|
||||
def c_vk_version(self): |
||||
ver_list = [str(self.major), str(self.minor), str(self.patch or 0)] |
||||
return 'VK_MAKE_VERSION(' + ', '.join(ver_list) + ')' |
||||
|
||||
def __int_ver(self): |
||||
# This is just an expansion of VK_VERSION |
||||
return (self.major << 22) | (self.minor << 12) | (self.patch or 0) |
||||
|
||||
def __gt__(self, other): |
||||
# If only one of them has a patch version, "ignore" it by making |
||||
# other's patch version match self. |
||||
if (self.patch is None) != (other.patch is None): |
||||
other = copy.copy(other) |
||||
other.patch = self.patch |
||||
|
||||
return self.__int_ver() > other.__int_ver() |
||||
|
||||
# Sort the extension list the way we expect: KHR, then EXT, then vendors |
||||
# alphabetically. For digits, read them as a whole number sort that. |
||||
# eg.: VK_KHR_8bit_storage < VK_KHR_16bit_storage < VK_EXT_acquire_xlib_display |
||||
def extension_order(ext): |
||||
order = [] |
||||
for substring in re.split('(KHR|EXT|[0-9]+)', ext.name): |
||||
if substring == 'KHR': |
||||
order.append(1) |
||||
if substring == 'EXT': |
||||
order.append(2) |
||||
elif substring.isdigit(): |
||||
order.append(int(substring)) |
||||
else: |
||||
order.append(substring) |
||||
return order |
||||
|
||||
def get_all_exts_from_xml(xml, api='vulkan'): |
||||
""" Get a list of all Vulkan extensions. """ |
||||
|
||||
xml = et.parse(xml) |
||||
|
||||
extensions = [] |
||||
for ext_elem in xml.findall('.extensions/extension'): |
||||
ext = Extension.from_xml(ext_elem) |
||||
if api in ext.supported: |
||||
extensions.append(ext) |
||||
|
||||
return sorted(extensions, key=extension_order) |
||||
|
||||
def init_exts_from_xml(xml, extensions, platform_defines): |
||||
""" Walk the Vulkan XML and fill out extra extension information. """ |
||||
|
||||
xml = et.parse(xml) |
||||
|
||||
ext_name_map = {} |
||||
for ext in extensions: |
||||
ext_name_map[ext.name] = ext |
||||
|
||||
# KHR_display is missing from the list. |
||||
platform_defines.append('VK_USE_PLATFORM_DISPLAY_KHR') |
||||
for platform in xml.findall('./platforms/platform'): |
||||
platform_defines.append(platform.attrib['protect']) |
||||
|
||||
for ext_elem in xml.findall('.extensions/extension'): |
||||
ext_name = ext_elem.attrib['name'] |
||||
if ext_name not in ext_name_map: |
||||
continue |
||||
|
||||
ext = ext_name_map[ext_name] |
||||
ext.type = ext_elem.attrib['type'] |
||||
|
||||
class Requirements: |
||||
def __init__(self, core_version=None): |
||||
self.core_version = core_version |
||||
self.extensions = [] |
||||
self.guard = None |
||||
|
||||
def add_extension(self, ext): |
||||
for e in self.extensions: |
||||
if e == ext: |
||||
return; |
||||
assert e.name != ext.name |
||||
|
||||
self.extensions.append(ext) |
||||
|
||||
def filter_api(elem, api): |
||||
if 'api' not in elem.attrib: |
||||
return True |
||||
|
||||
return api in elem.attrib['api'].split(',') |
||||
|
||||
def get_all_required(xml, thing, api, beta): |
||||
things = {} |
||||
for feature in xml.findall('./feature'): |
||||
if not filter_api(feature, api): |
||||
continue |
||||
|
||||
version = VkVersion(feature.attrib['number']) |
||||
for t in feature.findall('./require/' + thing): |
||||
name = t.attrib['name'] |
||||
assert name not in things |
||||
things[name] = Requirements(core_version=version) |
||||
|
||||
for extension in xml.findall('.extensions/extension'): |
||||
ext = Extension.from_xml(extension) |
||||
if api not in ext.supported: |
||||
continue |
||||
|
||||
if beta != 'true' and ext.provisional: |
||||
continue |
||||
|
||||
for require in extension.findall('./require'): |
||||
if not filter_api(require, api): |
||||
continue |
||||
|
||||
for t in require.findall('./' + thing): |
||||
name = t.attrib['name'] |
||||
r = things.setdefault(name, Requirements()) |
||||
r.add_extension(ext) |
||||
|
||||
platform_defines = {} |
||||
for platform in xml.findall('./platforms/platform'): |
||||
name = platform.attrib['name'] |
||||
define = platform.attrib['protect'] |
||||
platform_defines[name] = define |
||||
|
||||
for req in things.values(): |
||||
if req.core_version is not None: |
||||
continue |
||||
|
||||
for ext in req.extensions: |
||||
if ext.platform in platform_defines: |
||||
req.guard = platform_defines[ext.platform] |
||||
break |
||||
|
||||
return things |
||||
|
||||
# Mapping between extension name and the android version in which the extension |
||||
# was whitelisted in Android CTS's dEQP-VK.info.device_extensions and |
||||
# dEQP-VK.api.info.android.no_unknown_extensions, excluding those blocked by |
||||
# android.graphics.cts.VulkanFeaturesTest#testVulkanBlockedExtensions. |
||||
ALLOWED_ANDROID_VERSION = { |
||||
# checkInstanceExtensions on oreo-cts-release |
||||
"VK_KHR_surface": 26, |
||||
"VK_KHR_display": 26, |
||||
"VK_KHR_android_surface": 26, |
||||
"VK_KHR_mir_surface": 26, |
||||
"VK_KHR_wayland_surface": 26, |
||||
"VK_KHR_win32_surface": 26, |
||||
"VK_KHR_xcb_surface": 26, |
||||
"VK_KHR_xlib_surface": 26, |
||||
"VK_KHR_get_physical_device_properties2": 26, |
||||
"VK_KHR_get_surface_capabilities2": 26, |
||||
"VK_KHR_external_memory_capabilities": 26, |
||||
"VK_KHR_external_semaphore_capabilities": 26, |
||||
"VK_KHR_external_fence_capabilities": 26, |
||||
# on pie-cts-release |
||||
"VK_KHR_device_group_creation": 28, |
||||
"VK_KHR_get_display_properties2": 28, |
||||
# on android10-tests-release |
||||
"VK_KHR_surface_protected_capabilities": 29, |
||||
# on android13-tests-release |
||||
"VK_KHR_portability_enumeration": 33, |
||||
|
||||
# checkDeviceExtensions on oreo-cts-release |
||||
"VK_KHR_swapchain": 26, |
||||
"VK_KHR_display_swapchain": 26, |
||||
"VK_KHR_sampler_mirror_clamp_to_edge": 26, |
||||
"VK_KHR_shader_draw_parameters": 26, |
||||
"VK_KHR_maintenance1": 26, |
||||
"VK_KHR_push_descriptor": 26, |
||||
"VK_KHR_descriptor_update_template": 26, |
||||
"VK_KHR_incremental_present": 26, |
||||
"VK_KHR_shared_presentable_image": 26, |
||||
"VK_KHR_storage_buffer_storage_class": 26, |
||||
"VK_KHR_16bit_storage": 26, |
||||
"VK_KHR_get_memory_requirements2": 26, |
||||
"VK_KHR_external_memory": 26, |
||||
"VK_KHR_external_memory_fd": 26, |
||||
"VK_KHR_external_memory_win32": 26, |
||||
"VK_KHR_external_semaphore": 26, |
||||
"VK_KHR_external_semaphore_fd": 26, |
||||
"VK_KHR_external_semaphore_win32": 26, |
||||
"VK_KHR_external_fence": 26, |
||||
"VK_KHR_external_fence_fd": 26, |
||||
"VK_KHR_external_fence_win32": 26, |
||||
"VK_KHR_win32_keyed_mutex": 26, |
||||
"VK_KHR_dedicated_allocation": 26, |
||||
"VK_KHR_variable_pointers": 26, |
||||
"VK_KHR_relaxed_block_layout": 26, |
||||
"VK_KHR_bind_memory2": 26, |
||||
"VK_KHR_maintenance2": 26, |
||||
"VK_KHR_image_format_list": 26, |
||||
"VK_KHR_sampler_ycbcr_conversion": 26, |
||||
# on oreo-mr1-cts-release |
||||
"VK_KHR_draw_indirect_count": 27, |
||||
# on pie-cts-release |
||||
"VK_KHR_device_group": 28, |
||||
"VK_KHR_multiview": 28, |
||||
"VK_KHR_maintenance3": 28, |
||||
"VK_KHR_create_renderpass2": 28, |
||||
"VK_KHR_driver_properties": 28, |
||||
# on android10-tests-release |
||||
"VK_KHR_shader_float_controls": 29, |
||||
"VK_KHR_shader_float16_int8": 29, |
||||
"VK_KHR_8bit_storage": 29, |
||||
"VK_KHR_depth_stencil_resolve": 29, |
||||
"VK_KHR_swapchain_mutable_format": 29, |
||||
"VK_KHR_shader_atomic_int64": 29, |
||||
"VK_KHR_vulkan_memory_model": 29, |
||||
"VK_KHR_swapchain_mutable_format": 29, |
||||
"VK_KHR_uniform_buffer_standard_layout": 29, |
||||
# on android11-tests-release |
||||
"VK_KHR_imageless_framebuffer": 30, |
||||
"VK_KHR_shader_subgroup_extended_types": 30, |
||||
"VK_KHR_buffer_device_address": 30, |
||||
"VK_KHR_separate_depth_stencil_layouts": 30, |
||||
"VK_KHR_timeline_semaphore": 30, |
||||
"VK_KHR_spirv_1_4": 30, |
||||
"VK_KHR_pipeline_executable_properties": 30, |
||||
"VK_KHR_shader_clock": 30, |
||||
# blocked by testVulkanBlockedExtensions |
||||
# "VK_KHR_performance_query": 30, |
||||
"VK_KHR_shader_non_semantic_info": 30, |
||||
"VK_KHR_copy_commands2": 30, |
||||
# on android12-tests-release |
||||
"VK_KHR_shader_terminate_invocation": 31, |
||||
"VK_KHR_ray_tracing_pipeline": 31, |
||||
"VK_KHR_ray_query": 31, |
||||
"VK_KHR_acceleration_structure": 31, |
||||
"VK_KHR_pipeline_library": 31, |
||||
"VK_KHR_deferred_host_operations": 31, |
||||
"VK_KHR_fragment_shading_rate": 31, |
||||
"VK_KHR_zero_initialize_workgroup_memory": 31, |
||||
"VK_KHR_workgroup_memory_explicit_layout": 31, |
||||
"VK_KHR_synchronization2": 31, |
||||
"VK_KHR_shader_integer_dot_product": 31, |
||||
# on android13-tests-release |
||||
"VK_KHR_dynamic_rendering": 33, |
||||
"VK_KHR_format_feature_flags2": 33, |
||||
"VK_KHR_global_priority": 33, |
||||
"VK_KHR_maintenance4": 33, |
||||
"VK_KHR_portability_subset": 33, |
||||
"VK_KHR_present_id": 33, |
||||
"VK_KHR_present_wait": 33, |
||||
"VK_KHR_shader_subgroup_uniform_control_flow": 33, |
||||
|
||||
# testNoUnknownExtensions on oreo-cts-release |
||||
"VK_GOOGLE_display_timing": 26, |
||||
# on pie-cts-release |
||||
"VK_ANDROID_external_memory_android_hardware_buffer": 28, |
||||
# on android11-tests-release |
||||
"VK_GOOGLE_decorate_string": 30, |
||||
"VK_GOOGLE_hlsl_functionality1": 30, |
||||
# on android13-tests-release |
||||
"VK_GOOGLE_surfaceless_query": 33, |
||||
|
||||
# this HAL extension is always allowed and will be filtered out by the |
||||
# loader |
||||
"VK_ANDROID_native_buffer": 26, |
||||
} |
||||
|
||||
# Extensions with these prefixes are checked in Android CTS, and thus must be |
||||
# whitelisted per the preceding dict. |
||||
ANDROID_EXTENSION_WHITELIST_PREFIXES = ( |
||||
"VK_KHX", |
||||
"VK_KHR", |
||||
"VK_GOOGLE", |
||||
"VK_ANDROID" |
||||
) |
@ -0,0 +1,108 @@ |
||||
#include <stdint.h> |
||||
|
||||
#include <vulkan/vulkan.h> |
||||
|
||||
// generated by util/gen_enum_to_str.py from the mesa project
|
||||
const char *vk_Result_to_str(VkResult input) |
||||
{ |
||||
switch ((int64_t)input) { |
||||
case -1000338000: |
||||
return "VK_ERROR_COMPRESSION_EXHAUSTED_EXT"; |
||||
case -1000299000: |
||||
return "VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR"; |
||||
case -1000257000: |
||||
return "VK_ERROR_INVALID_DEVICE_ADDRESS_EXT"; |
||||
case -1000255000: |
||||
return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; |
||||
case -1000174001: |
||||
return "VK_ERROR_NOT_PERMITTED_KHR"; |
||||
case -1000161000: |
||||
return "VK_ERROR_FRAGMENTATION"; |
||||
case -1000158000: |
||||
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; |
||||
case -1000072003: |
||||
return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; |
||||
case -1000069000: |
||||
return "VK_ERROR_OUT_OF_POOL_MEMORY"; |
||||
case -1000023005: |
||||
return "VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR"; |
||||
case -1000023004: |
||||
return "VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR"; |
||||
case -1000023003: |
||||
return "VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR"; |
||||
case -1000023002: |
||||
return "VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR"; |
||||
case -1000023001: |
||||
return "VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR"; |
||||
case -1000023000: |
||||
return "VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR"; |
||||
case -1000012000: |
||||
return "VK_ERROR_INVALID_SHADER_NV"; |
||||
case -1000011001: |
||||
return "VK_ERROR_VALIDATION_FAILED_EXT"; |
||||
case -1000003001: |
||||
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; |
||||
case -1000001004: |
||||
return "VK_ERROR_OUT_OF_DATE_KHR"; |
||||
case -1000000001: |
||||
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; |
||||
case -1000000000: |
||||
return "VK_ERROR_SURFACE_LOST_KHR"; |
||||
case -13: |
||||
return "VK_ERROR_UNKNOWN"; |
||||
case -12: |
||||
return "VK_ERROR_FRAGMENTED_POOL"; |
||||
case -11: |
||||
return "VK_ERROR_FORMAT_NOT_SUPPORTED"; |
||||
case -10: |
||||
return "VK_ERROR_TOO_MANY_OBJECTS"; |
||||
case -9: |
||||
return "VK_ERROR_INCOMPATIBLE_DRIVER"; |
||||
case -8: |
||||
return "VK_ERROR_FEATURE_NOT_PRESENT"; |
||||
case -7: |
||||
return "VK_ERROR_EXTENSION_NOT_PRESENT"; |
||||
case -6: |
||||
return "VK_ERROR_LAYER_NOT_PRESENT"; |
||||
case -5: |
||||
return "VK_ERROR_MEMORY_MAP_FAILED"; |
||||
case -4: |
||||
return "VK_ERROR_DEVICE_LOST"; |
||||
case -3: |
||||
return "VK_ERROR_INITIALIZATION_FAILED"; |
||||
case -2: |
||||
return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; |
||||
case -1: |
||||
return "VK_ERROR_OUT_OF_HOST_MEMORY"; |
||||
case 0: |
||||
return "VK_SUCCESS"; |
||||
case 1: |
||||
return "VK_NOT_READY"; |
||||
case 2: |
||||
return "VK_TIMEOUT"; |
||||
case 3: |
||||
return "VK_EVENT_SET"; |
||||
case 4: |
||||
return "VK_EVENT_RESET"; |
||||
case 5: |
||||
return "VK_INCOMPLETE"; |
||||
case 1000001003: |
||||
return "VK_SUBOPTIMAL_KHR"; |
||||
case 1000268000: |
||||
return "VK_THREAD_IDLE_KHR"; |
||||
case 1000268001: |
||||
return "VK_THREAD_DONE_KHR"; |
||||
case 1000268002: |
||||
return "VK_OPERATION_DEFERRED_KHR"; |
||||
case 1000268003: |
||||
return "VK_OPERATION_NOT_DEFERRED_KHR"; |
||||
case 1000297000: |
||||
return "VK_PIPELINE_COMPILE_REQUIRED"; |
||||
case 1000482000: |
||||
return "VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT"; |
||||
case VK_RESULT_MAX_ENUM: |
||||
return "VK_RESULT_MAX_ENUM"; |
||||
default: |
||||
return "Unknown VkResult value."; |
||||
} |
||||
} |
Loading…
Reference in new issue