holy
This commit is contained in:
parent
68bea8a225
commit
ee79b4c195
2
test3/.gitignore
vendored
Normal file
2
test3/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
test3
|
22
test3/Makefile
Normal file
22
test3/Makefile
Normal file
@ -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
|
1
test3/README
Normal file
1
test3/README
Normal file
@ -0,0 +1 @@
|
||||
Trying to implement test2 with just vulkan and in C
|
328
test3/main.c
Normal file
328
test3/main.c
Normal file
@ -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;
|
||||
}
|
3
test3/util/.gitignore
vendored
Normal file
3
test3/util/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
__pycache__
|
||||
out
|
||||
vk.xml
|
6
test3/util/Makefile
Normal file
6
test3/util/Makefile
Normal file
@ -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
|
||||
|
573
test3/util/gen_enum_to_str.py
Normal file
573
test3/util/gen_enum_to_str.py
Normal file
@ -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()
|
3
test3/util/test_sse.sh
Executable file
3
test3/util/test_sse.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
gcc -msse3 -dM -E - < /dev/null | grep -E "SSE|AVX" | sort
|
356
test3/util/vk_extensions.py
Normal file
356
test3/util/vk_extensions.py
Normal file
@ -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"
|
||||
)
|
108
test3/vk_result_to_str.c
Normal file
108
test3/vk_result_to_str.c
Normal file
@ -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
Block a user