Merge "SF: Add workaround to release screenshot buffer" into pi-dev
am: 6fa25f9d8f
Change-Id: I20c44440a717fd704fa8b73540ccdd358e8636a8
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index fe9dd56..2561e0a 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -118,6 +118,7 @@
{ "adb", "ADB", ATRACE_TAG_ADB, { } },
{ "vibrator", "Vibrator", ATRACE_TAG_VIBRATOR, { } },
{ "aidl", "AIDL calls", ATRACE_TAG_AIDL, { } },
+ { "nnapi", "NNAPI", ATRACE_TAG_NNAPI, { } },
{ k_coreServiceCategory, "Core services", 0, { } },
{ k_pdxServiceCategory, "PDX services", 0, { } },
{ "sched", "CPU Scheduling", 0, {
@@ -1285,9 +1286,7 @@
if (!onlyUserspace)
ok = clearTrace();
- if (!onlyUserspace)
- writeClockSyncMarker();
-
+ writeClockSyncMarker();
if (ok && !async && !traceStream) {
// Sleep to allow the trace to be captured.
struct timespec timeLeft;
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index d3d0711..579cfaf 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -90,6 +90,10 @@
# disk
+ chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_get_data_block/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_get_data_block/enable
+ chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_iget/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_iget/enable
chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_enter/enable
chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_enter/enable
chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_exit/enable
@@ -102,6 +106,12 @@
chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_begin/enable
chmod 0666 /sys/kernel/tracing/events/ext4/ext4_da_write_end/enable
chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_end/enable
+ chmod 0666 /sys/kernel/tracing/events/ext4/ext4_es_lookup_extent_enter/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_es_lookup_extent_enter/enable
+ chmod 0666 /sys/kernel/tracing/events/ext4/ext4_es_lookup_extent_exit/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_es_lookup_extent_exit/enable
+ chmod 0666 /sys/kernel/tracing/events/ext4/ext4_load_inode/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_load_inode/enable
chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_enter/enable
chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable
chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_exit/enable
@@ -125,6 +135,42 @@
chmod 0666 /sys/kernel/debug/tracing/trace
chmod 0666 /sys/kernel/tracing/trace
+# Read and truncate the per-CPU kernel trace.
+# Cannot use wildcards in .rc files. Update this if there is a phone with
+# more CPUs.
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu0/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu0/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu1/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu1/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu2/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu2/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu3/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu3/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu4/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu4/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu5/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu5/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu6/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu6/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu6/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu7/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu8/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu8/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu9/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu9/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu10/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu10/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu11/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu11/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu12/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu12/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu13/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu13/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu14/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu14/trace
+ chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu15/trace
+ chmod 0666 /sys/kernel/tracing/per_cpu/cpu15/trace
+
on property:persist.debug.atrace.boottrace=1
start boottrace
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 48d5d4a..4238531 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -167,13 +167,6 @@
{
signal(SIGPIPE, SIG_IGN);
sp<ProcessState> proc = ProcessState::self();
- // setThreadPoolMaxThreadCount(0) actually tells the kernel it's
- // not allowed to spawn any additional threads, but we still spawn
- // a binder thread from userspace when we call startThreadPool().
- // This is safe because we only have 2 callbacks, neither of which
- // block.
- // See b/36066697 for rationale
- proc->setThreadPoolMaxThreadCount(0);
proc->startThreadPool();
#if DEBUG
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 9d897f5..2b62415 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -333,7 +333,7 @@
}
// find anrd's pid if it is running.
- pid = GetPidByName("/system/xbin/anrd");
+ pid = GetPidByName("/system/bin/anrd");
if (pid > 0) {
if (stat(trace_path, &st) == 0) {
@@ -926,53 +926,6 @@
RunCommand("IP6TABLES RAW", {"ip6tables", "-t", "raw", "-L", "-nvx"});
}
-static void AddGlobalAnrTraceFile(const bool add_to_zip, const std::string& anr_traces_file,
- const std::string& anr_traces_dir) {
- std::string dump_traces_dir;
-
- if (dump_traces_path != nullptr) {
- if (add_to_zip) {
- dump_traces_dir = dirname(dump_traces_path);
- MYLOGD("Adding ANR traces (directory %s) to the zip file\n", dump_traces_dir.c_str());
- ds.AddDir(dump_traces_dir, true);
- } else {
- MYLOGD("Dumping current ANR traces (%s) to the main bugreport entry\n",
- dump_traces_path);
- ds.DumpFile("VM TRACES JUST NOW", dump_traces_path);
- }
- }
-
-
- // Make sure directory is not added twice.
- // TODO: this is an overzealous check because it's relying on dump_traces_path - which is
- // generated by dump_traces() - and anr_traces_path - which is retrieved from a system
- // property - but in reality they're the same path (although the former could be nullptr).
- // Anyways, once dump_traces() is refactored as a private Dumpstate function, this logic should
- // be revisited.
- bool already_dumped = anr_traces_dir == dump_traces_dir;
-
- MYLOGD("AddGlobalAnrTraceFile(): dump_traces_dir=%s, anr_traces_dir=%s, already_dumped=%d\n",
- dump_traces_dir.c_str(), anr_traces_dir.c_str(), already_dumped);
-
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(
- open(anr_traces_file.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK)));
- if (fd.get() < 0) {
- printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_file.c_str(), strerror(errno));
- } else {
- if (add_to_zip) {
- if (!already_dumped) {
- MYLOGD("Adding dalvik ANR traces (directory %s) to the zip file\n",
- anr_traces_dir.c_str());
- ds.AddDir(anr_traces_dir, true);
- }
- } else {
- MYLOGD("Dumping last ANR traces (%s) to the main bugreport entry\n",
- anr_traces_file.c_str());
- dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_file.c_str(), fd.get());
- }
- }
-}
-
static void AddAnrTraceDir(const bool add_to_zip, const std::string& anr_traces_dir) {
MYLOGD("AddAnrTraceDir(): dump_traces_file=%s, anr_traces_dir=%s\n", dump_traces_path,
anr_traces_dir.c_str());
@@ -1015,50 +968,22 @@
static void AddAnrTraceFiles() {
const bool add_to_zip = ds.IsZipping() && ds.version_ == VERSION_SPLIT_ANR;
- std::string anr_traces_file;
- std::string anr_traces_dir;
- bool is_global_trace_file = true;
+ std::string anr_traces_dir = "/data/anr";
- // First check whether the stack-trace-dir property is set. When it's set,
- // each ANR trace will be written to a separate file and not to a global
- // stack trace file.
- anr_traces_dir = android::base::GetProperty("dalvik.vm.stack-trace-dir", "");
- if (anr_traces_dir.empty()) {
- anr_traces_file = android::base::GetProperty("dalvik.vm.stack-trace-file", "");
- if (!anr_traces_file.empty()) {
- anr_traces_dir = dirname(anr_traces_file.c_str());
- }
- } else {
- is_global_trace_file = false;
- }
+ AddAnrTraceDir(add_to_zip, anr_traces_dir);
- // We have neither configured a global trace file nor a trace directory,
- // there will be nothing to dump.
- if (anr_traces_file.empty() && anr_traces_dir.empty()) {
- printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
- return;
- }
-
- if (is_global_trace_file) {
- AddGlobalAnrTraceFile(add_to_zip, anr_traces_file, anr_traces_dir);
- } else {
- AddAnrTraceDir(add_to_zip, anr_traces_dir);
- }
-
- /* slow traces for slow operations */
+ // Slow traces for slow operations.
struct stat st;
- if (!anr_traces_dir.empty()) {
- int i = 0;
- while (true) {
- const std::string slow_trace_path =
- anr_traces_dir + android::base::StringPrintf("slow%02d.txt", i);
- if (stat(slow_trace_path.c_str(), &st)) {
- // No traces file at this index, done with the files.
- break;
- }
- ds.DumpFile("VM TRACES WHEN SLOW", slow_trace_path.c_str());
- i++;
+ int i = 0;
+ while (true) {
+ const std::string slow_trace_path =
+ anr_traces_dir + android::base::StringPrintf("slow%02d.txt", i);
+ if (stat(slow_trace_path.c_str(), &st)) {
+ // No traces file at this index, done with the files.
+ break;
}
+ ds.DumpFile("VM TRACES WHEN SLOW", slow_trace_path.c_str());
+ i++;
}
}
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 022f4fc..9beff98 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -779,29 +779,11 @@
_redirect_to_file(redirect, path, O_APPEND);
}
-const char* DumpTraces(const std::string& traces_path);
-const char* DumpTracesTombstoned(const std::string& traces_dir);
-
-/* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
-const char *dump_traces() {
+// Dump Dalvik and native stack traces, return the trace file location (nullptr if none).
+const char* dump_traces() {
DurationReporter duration_reporter("DUMP TRACES");
- const std::string traces_dir = android::base::GetProperty("dalvik.vm.stack-trace-dir", "");
- if (!traces_dir.empty()) {
- return DumpTracesTombstoned(traces_dir);
- }
-
- const std::string traces_file = android::base::GetProperty("dalvik.vm.stack-trace-file", "");
- if (!traces_file.empty()) {
- return DumpTraces(traces_file);
- }
-
- return nullptr;
-}
-
-const char* DumpTracesTombstoned(const std::string& traces_dir) {
- const std::string temp_file_pattern = traces_dir + "/dumptrace_XXXXXX";
-
+ const std::string temp_file_pattern = "/data/anr/dumptrace_XXXXXX";
const size_t buf_size = temp_file_pattern.length() + 1;
std::unique_ptr<char[]> file_name_buf(new char[buf_size]);
memcpy(file_name_buf.get(), temp_file_pattern.c_str(), buf_size);
@@ -902,156 +884,6 @@
return file_name_buf.release();
}
-const char* DumpTraces(const std::string& traces_path) {
- const char* result = NULL;
- /* move the old traces.txt (if any) out of the way temporarily */
- std::string anrtraces_path = traces_path + ".anr";
- if (rename(traces_path.c_str(), anrtraces_path.c_str()) && errno != ENOENT) {
- MYLOGE("rename(%s, %s): %s\n", traces_path.c_str(), anrtraces_path.c_str(), strerror(errno));
- return nullptr; // Can't rename old traces.txt -- no permission? -- leave it alone instead
- }
-
- /* create a new, empty traces.txt file to receive stack dumps */
- int fd = TEMP_FAILURE_RETRY(
- open(traces_path.c_str(), O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
- 0666)); /* -rw-rw-rw- */
- if (fd < 0) {
- MYLOGE("%s: %s\n", traces_path.c_str(), strerror(errno));
- return nullptr;
- }
- int chmod_ret = fchmod(fd, 0666);
- if (chmod_ret < 0) {
- MYLOGE("fchmod on %s failed: %s\n", traces_path.c_str(), strerror(errno));
- close(fd);
- return nullptr;
- }
-
- /* Variables below must be initialized before 'goto' statements */
- int dalvik_found = 0;
- int ifd, wfd = -1;
- std::set<int> hal_pids = get_interesting_hal_pids();
-
- /* walk /proc and kill -QUIT all Dalvik processes */
- DIR *proc = opendir("/proc");
- if (proc == NULL) {
- MYLOGE("/proc: %s\n", strerror(errno));
- goto error_close_fd;
- }
-
- /* use inotify to find when processes are done dumping */
- ifd = inotify_init();
- if (ifd < 0) {
- MYLOGE("inotify_init: %s\n", strerror(errno));
- goto error_close_fd;
- }
-
- wfd = inotify_add_watch(ifd, traces_path.c_str(), IN_CLOSE_WRITE);
- if (wfd < 0) {
- MYLOGE("inotify_add_watch(%s): %s\n", traces_path.c_str(), strerror(errno));
- goto error_close_ifd;
- }
-
- struct dirent *d;
- while ((d = readdir(proc))) {
- int pid = atoi(d->d_name);
- if (pid <= 0) continue;
-
- char path[PATH_MAX];
- char data[PATH_MAX];
- snprintf(path, sizeof(path), "/proc/%d/exe", pid);
- ssize_t len = readlink(path, data, sizeof(data) - 1);
- if (len <= 0) {
- continue;
- }
- data[len] = '\0';
-
- if (!strncmp(data, "/system/bin/app_process", strlen("/system/bin/app_process"))) {
- /* skip zygote -- it won't dump its stack anyway */
- snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
- int cfd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC));
- len = read(cfd, data, sizeof(data) - 1);
- close(cfd);
- if (len <= 0) {
- continue;
- }
- data[len] = '\0';
- if (!strncmp(data, "zygote", strlen("zygote"))) {
- continue;
- }
-
- ++dalvik_found;
- uint64_t start = Nanotime();
- if (kill(pid, SIGQUIT)) {
- MYLOGE("kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
- continue;
- }
-
- /* wait for the writable-close notification from inotify */
- struct pollfd pfd = { ifd, POLLIN, 0 };
- int ret = poll(&pfd, 1, TRACE_DUMP_TIMEOUT_MS);
- if (ret < 0) {
- MYLOGE("poll: %s\n", strerror(errno));
- } else if (ret == 0) {
- MYLOGE("warning: timed out dumping pid %d\n", pid);
- } else {
- struct inotify_event ie;
- read(ifd, &ie, sizeof(ie));
- }
-
- if (lseek(fd, 0, SEEK_END) < 0) {
- MYLOGE("lseek: %s\n", strerror(errno));
- } else {
- dprintf(fd, "[dump dalvik stack %d: %.3fs elapsed]\n", pid,
- (float)(Nanotime() - start) / NANOS_PER_SEC);
- }
- } else if (should_dump_native_traces(data) ||
- hal_pids.find(pid) != hal_pids.end()) {
- /* dump native process if appropriate */
- if (lseek(fd, 0, SEEK_END) < 0) {
- MYLOGE("lseek: %s\n", strerror(errno));
- } else {
- static uint16_t timeout_failures = 0;
- uint64_t start = Nanotime();
-
- /* If 3 backtrace dumps fail in a row, consider debuggerd dead. */
- if (timeout_failures == 3) {
- dprintf(fd, "too many stack dump failures, skipping...\n");
- } else if (dump_backtrace_to_file_timeout(
- pid, kDebuggerdNativeBacktrace, 20, fd) == -1) {
- dprintf(fd, "dumping failed, likely due to a timeout\n");
- timeout_failures++;
- } else {
- timeout_failures = 0;
- }
- dprintf(fd, "[dump native stack %d: %.3fs elapsed]\n", pid,
- (float)(Nanotime() - start) / NANOS_PER_SEC);
- }
- }
- }
-
- if (dalvik_found == 0) {
- MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
- }
-
- static std::string dumptraces_path = android::base::StringPrintf(
- "%s/bugreport-%s", dirname(traces_path.c_str()), basename(traces_path.c_str()));
- if (rename(traces_path.c_str(), dumptraces_path.c_str())) {
- MYLOGE("rename(%s, %s): %s\n", traces_path.c_str(), dumptraces_path.c_str(),
- strerror(errno));
- goto error_close_ifd;
- }
- result = dumptraces_path.c_str();
-
- /* replace the saved [ANR] traces.txt file */
- rename(anrtraces_path.c_str(), traces_path.c_str());
-
-error_close_ifd:
- close(ifd);
-error_close_fd:
- close(fd);
- return result;
-}
-
void dump_route_tables() {
DurationReporter duration_reporter("DUMP ROUTE TABLES");
if (PropertiesHelper::IsDryRun()) return;
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 9615a75..fa23d3a 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_TAG "installed"
+#define LOG_TAG "installd"
#include <array>
#include <fcntl.h>
diff --git a/cmds/installd/tests/Android.bp b/cmds/installd/tests/Android.bp
index 7438d3d..739f33f 100644
--- a/cmds/installd/tests/Android.bp
+++ b/cmds/installd/tests/Android.bp
@@ -1,6 +1,7 @@
// Build the unit tests for installd
cc_test {
name: "installd_utils_test",
+ test_suites: ["device-tests"],
clang: true,
srcs: ["installd_utils_test.cpp"],
cflags: ["-Wall", "-Werror"],
@@ -18,6 +19,7 @@
cc_test {
name: "installd_cache_test",
+ test_suites: ["device-tests"],
clang: true,
srcs: ["installd_cache_test.cpp"],
cflags: ["-Wall", "-Werror"],
@@ -39,6 +41,7 @@
cc_test {
name: "installd_service_test",
+ test_suites: ["device-tests"],
clang: true,
srcs: ["installd_service_test.cpp"],
cflags: ["-Wall", "-Werror"],
@@ -60,6 +63,7 @@
cc_test {
name: "installd_dexopt_test",
+ test_suites: ["device-tests"],
clang: true,
srcs: ["installd_dexopt_test.cpp"],
cflags: ["-Wall", "-Werror"],
@@ -81,6 +85,7 @@
cc_test {
name: "installd_otapreopt_test",
+ test_suites: ["device-tests"],
clang: true,
srcs: ["installd_otapreopt_test.cpp"],
cflags: ["-Wall", "-Werror"],
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index dd8812d..0952db6 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -59,8 +59,8 @@
auto pair = splitFirst(mInterfaceName, '/');
- FQName fqName(pair.first);
- if (!fqName.isValid() || fqName.isIdentifier() || !fqName.isFullyQualified()) {
+ FQName fqName;
+ if (!FQName::parse(pair.first, &fqName) || fqName.isIdentifier() || !fqName.isFullyQualified()) {
mLshal.err() << "Invalid fully-qualified name '" << pair.first << "'\n\n";
return USAGE;
}
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index ff22048..92e9151 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -18,14 +18,17 @@
#include <getopt.h>
+#include <algorithm>
#include <fstream>
+#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
-#include <sstream>
#include <regex>
+#include <sstream>
#include <android-base/file.h>
+#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl-hash/Hash.h>
@@ -101,21 +104,19 @@
// Give sensible defaults when nothing can be inferred from runtime.
// process: Partition inferred from executable location or cmdline.
-Partition ListCommand::resolvePartition(Partition process, const FQName& fqName) const {
- if (fqName.inPackage("vendor") ||
- fqName.inPackage("com")) {
+Partition ListCommand::resolvePartition(Partition process, const FqInstance& fqInstance) const {
+ if (fqInstance.inPackage("vendor") || fqInstance.inPackage("com")) {
return Partition::VENDOR;
}
- if (fqName.inPackage("android.frameworks") ||
- fqName.inPackage("android.system") ||
- fqName.inPackage("android.hidl")) {
+ if (fqInstance.inPackage("android.frameworks") || fqInstance.inPackage("android.system") ||
+ fqInstance.inPackage("android.hidl")) {
return Partition::SYSTEM;
}
// Some android.hardware HALs are served from system. Check the value from executable
// location / cmdline first.
- if (fqName.inPackage("android.hardware")) {
+ if (fqInstance.inPackage("android.hardware")) {
if (process != Partition::UNKNOWN) {
return process;
}
@@ -125,6 +126,67 @@
return process;
}
+bool match(const vintf::ManifestInstance& instance, const FqInstance& fqInstance,
+ vintf::TransportArch ta) {
+ // For hwbinder libs, allow missing arch in manifest.
+ // For passthrough libs, allow missing interface/instance in table.
+ return (ta.transport == instance.transport()) &&
+ (ta.transport == vintf::Transport::HWBINDER ||
+ vintf::contains(instance.arch(), ta.arch)) &&
+ (!fqInstance.hasInterface() || fqInstance.getInterface() == instance.interface()) &&
+ (!fqInstance.hasInstance() || fqInstance.getInstance() == instance.instance());
+}
+
+bool match(const vintf::MatrixInstance& instance, const FqInstance& fqInstance,
+ vintf::TransportArch /* ta */) {
+ return (!fqInstance.hasInterface() || fqInstance.getInterface() == instance.interface()) &&
+ (!fqInstance.hasInstance() || instance.matchInstance(fqInstance.getInstance()));
+}
+
+template <typename ObjectType>
+VintfInfo getVintfInfo(const std::shared_ptr<const ObjectType>& object,
+ const FqInstance& fqInstance, vintf::TransportArch ta, VintfInfo value) {
+ bool found = false;
+ (void)object->forEachInstanceOfVersion(fqInstance.getPackage(), fqInstance.getVersion(),
+ [&](const auto& instance) {
+ found = match(instance, fqInstance, ta);
+ return !found; // continue if not found
+ });
+ return found ? value : VINTF_INFO_EMPTY;
+}
+
+std::shared_ptr<const vintf::HalManifest> ListCommand::getDeviceManifest() const {
+ return vintf::VintfObject::GetDeviceHalManifest();
+}
+
+std::shared_ptr<const vintf::CompatibilityMatrix> ListCommand::getDeviceMatrix() const {
+ return vintf::VintfObject::GetDeviceCompatibilityMatrix();
+}
+
+std::shared_ptr<const vintf::HalManifest> ListCommand::getFrameworkManifest() const {
+ return vintf::VintfObject::GetFrameworkHalManifest();
+}
+
+std::shared_ptr<const vintf::CompatibilityMatrix> ListCommand::getFrameworkMatrix() const {
+ return vintf::VintfObject::GetFrameworkCompatibilityMatrix();
+}
+
+VintfInfo ListCommand::getVintfInfo(const std::string& fqInstanceName,
+ vintf::TransportArch ta) const {
+ FqInstance fqInstance;
+ if (!fqInstance.setTo(fqInstanceName) &&
+ // Ignore interface / instance for passthrough libs
+ !fqInstance.setTo(splitFirst(fqInstanceName, ':').first)) {
+ err() << "Warning: Cannot parse '" << fqInstanceName << "'; no VINTF info." << std::endl;
+ return VINTF_INFO_EMPTY;
+ }
+
+ return lshal::getVintfInfo(getDeviceManifest(), fqInstance, ta, DEVICE_MANIFEST) |
+ lshal::getVintfInfo(getFrameworkManifest(), fqInstance, ta, FRAMEWORK_MANIFEST) |
+ lshal::getVintfInfo(getDeviceMatrix(), fqInstance, ta, DEVICE_MATRIX) |
+ lshal::getVintfInfo(getFrameworkMatrix(), fqInstance, ta, FRAMEWORK_MATRIX);
+}
+
static bool scanBinderContext(pid_t pid,
const std::string &contextName,
std::function<void(const std::string&)> eachLine) {
@@ -221,16 +283,37 @@
return &pair.first->second;
}
-// Must process hwbinder services first, then passthrough services.
+bool ListCommand::shouldReportHalType(const HalType &type) const {
+ return (std::find(mListTypes.begin(), mListTypes.end(), type) != mListTypes.end());
+}
+
void ListCommand::forEachTable(const std::function<void(Table &)> &f) {
- f(mServicesTable);
- f(mPassthroughRefTable);
- f(mImplementationsTable);
+ for (const auto& type : mListTypes) {
+ switch (type) {
+ case HalType::BINDERIZED_SERVICES:
+ f(mServicesTable); break;
+ case HalType::PASSTHROUGH_CLIENTS:
+ f(mPassthroughRefTable); break;
+ case HalType::PASSTHROUGH_LIBRARIES:
+ f(mImplementationsTable); break;
+ default:
+ LOG(FATAL) << __func__ << "Unknown HAL type.";
+ }
+ }
}
void ListCommand::forEachTable(const std::function<void(const Table &)> &f) const {
- f(mServicesTable);
- f(mPassthroughRefTable);
- f(mImplementationsTable);
+ for (const auto& type : mListTypes) {
+ switch (type) {
+ case HalType::BINDERIZED_SERVICES:
+ f(mServicesTable); break;
+ case HalType::PASSTHROUGH_CLIENTS:
+ f(mPassthroughRefTable); break;
+ case HalType::PASSTHROUGH_LIBRARIES:
+ f(mImplementationsTable); break;
+ default:
+ LOG(FATAL) << __func__ << "Unknown HAL type.";
+ }
+ }
}
void ListCommand::postprocess() {
@@ -247,21 +330,22 @@
}
for (TableEntry& entry : table) {
entry.partition = getPartition(entry.serverPid);
+ entry.vintfInfo = getVintfInfo(entry.interfaceName, {entry.transport, entry.arch});
}
});
// use a double for loop here because lshal doesn't care about efficiency.
for (TableEntry &packageEntry : mImplementationsTable) {
std::string packageName = packageEntry.interfaceName;
- FQName fqPackageName{packageName.substr(0, packageName.find("::"))};
- if (!fqPackageName.isValid()) {
+ FQName fqPackageName;
+ if (!FQName::parse(packageName.substr(0, packageName.find("::")), &fqPackageName)) {
continue;
}
for (TableEntry &interfaceEntry : mPassthroughRefTable) {
- if (interfaceEntry.arch != ARCH_UNKNOWN) {
+ if (interfaceEntry.arch != vintf::Arch::ARCH_EMPTY) {
continue;
}
- FQName interfaceName{splitFirst(interfaceEntry.interfaceName, '/').first};
- if (!interfaceName.isValid()) {
+ FQName interfaceName;
+ if (!FQName::parse(splitFirst(interfaceEntry.interfaceName, '/').first, &interfaceName)) {
continue;
}
if (interfaceName.getPackageAndVersion() == fqPackageName) {
@@ -284,149 +368,136 @@
"These may return subclasses through their respective HIDL_FETCH_I* functions.");
}
-static inline bool findAndBumpVersion(vintf::ManifestHal* hal, const vintf::Version& version) {
- for (vintf::Version& v : hal->versions) {
- if (v.majorVer == version.majorVer) {
- v.minorVer = std::max(v.minorVer, version.minorVer);
- return true;
- }
+bool ListCommand::addEntryWithInstance(const TableEntry& entry,
+ vintf::HalManifest* manifest) const {
+ FqInstance fqInstance;
+ if (!fqInstance.setTo(entry.interfaceName)) {
+ err() << "Warning: '" << entry.interfaceName << "' is not a valid FqInstance." << std::endl;
+ return false;
}
- return false;
+
+ if (fqInstance.getPackage() == gIBaseFqName.package()) {
+ return true; // always remove IBase from manifest
+ }
+
+ Partition partition = resolvePartition(entry.partition, fqInstance);
+
+ if (partition == Partition::UNKNOWN) {
+ err() << "Warning: Cannot guess the partition of FqInstance " << fqInstance.string()
+ << std::endl;
+ return false;
+ }
+
+ if (partition != mVintfPartition) {
+ return true; // strip out instances that is in a different partition.
+ }
+
+ vintf::Arch arch;
+ if (entry.transport == vintf::Transport::HWBINDER) {
+ arch = vintf::Arch::ARCH_EMPTY; // no need to specify arch in manifest
+ } else if (entry.transport == vintf::Transport::PASSTHROUGH) {
+ if (entry.arch == vintf::Arch::ARCH_EMPTY) {
+ err() << "Warning: '" << entry.interfaceName << "' doesn't have bitness info.";
+ return false;
+ }
+ arch = entry.arch;
+ } else {
+ err() << "Warning: '" << entry.transport << "' is not a valid transport." << std::endl;
+ return false;
+ }
+
+ std::string e;
+ if (!manifest->insertInstance(fqInstance, entry.transport, arch, vintf::HalFormat::HIDL, &e)) {
+ err() << "Warning: Cannot insert '" << fqInstance.string() << ": " << e << std::endl;
+ return false;
+ }
+ return true;
+}
+
+bool ListCommand::addEntryWithoutInstance(const TableEntry& entry,
+ const vintf::HalManifest* manifest) const {
+ const auto& packageAndVersion = splitFirst(splitFirst(entry.interfaceName, ':').first, '@');
+ const auto& package = packageAndVersion.first;
+ vintf::Version version;
+ if (!vintf::parse(packageAndVersion.second, &version)) {
+ err() << "Warning: Cannot parse version '" << packageAndVersion.second << "' for entry '"
+ << entry.interfaceName << "'" << std::endl;
+ return false;
+ }
+
+ bool found = false;
+ (void)manifest->forEachInstanceOfVersion(package, version, [&found](const auto&) {
+ found = true;
+ return false; // break
+ });
+ return found;
}
void ListCommand::dumpVintf(const NullableOStream<std::ostream>& out) const {
using vintf::operator|=;
using vintf::operator<<;
+ using namespace std::placeholders;
vintf::HalManifest manifest;
manifest.setType(toSchemaType(mVintfPartition));
- forEachTable([this, &manifest] (const Table &table) {
- for (const TableEntry &entry : table) {
- std::string fqInstanceName = entry.interfaceName;
+ std::vector<std::string> error;
+ for (const TableEntry& entry : mServicesTable)
+ if (!addEntryWithInstance(entry, &manifest)) error.push_back(entry.interfaceName);
+ for (const TableEntry& entry : mPassthroughRefTable)
+ if (!addEntryWithInstance(entry, &manifest)) error.push_back(entry.interfaceName);
- if (&table == &mImplementationsTable) {
- // Quick hack to work around *'s
- replaceAll(&fqInstanceName, '*', 'D');
- }
- auto splittedFqInstanceName = splitFirst(fqInstanceName, '/');
- FQName fqName(splittedFqInstanceName.first);
- if (!fqName.isValid()) {
- err() << "Warning: '" << splittedFqInstanceName.first
- << "' is not a valid FQName." << std::endl;
- continue;
- }
+ std::vector<std::string> passthrough;
+ for (const TableEntry& entry : mImplementationsTable)
+ if (!addEntryWithoutInstance(entry, &manifest)) passthrough.push_back(entry.interfaceName);
- if (fqName.package() == gIBaseFqName.package()) {
- continue; // always remove IBase from manifest
- }
-
- Partition partition = resolvePartition(entry.partition, fqName);
-
- if (partition == Partition::UNKNOWN) {
- err() << "Warning: Cannot guess the partition of instance " << fqInstanceName
- << ". It is removed from the generated manifest." << std::endl;
- continue;
- }
-
- if (partition != mVintfPartition) {
- continue; // strip out instances that is in a different partition.
- }
-
- std::string interfaceName =
- &table == &mImplementationsTable ? "" : fqName.name();
- std::string instanceName =
- &table == &mImplementationsTable ? "" : splittedFqInstanceName.second;
-
- vintf::Version version{fqName.getPackageMajorVersion(),
- fqName.getPackageMinorVersion()};
- vintf::Transport transport;
- vintf::Arch arch;
- if (entry.transport == "hwbinder") {
- transport = vintf::Transport::HWBINDER;
- arch = vintf::Arch::ARCH_EMPTY;
- } else if (entry.transport == "passthrough") {
- transport = vintf::Transport::PASSTHROUGH;
- switch (entry.arch) {
- case lshal::ARCH32:
- arch = vintf::Arch::ARCH_32; break;
- case lshal::ARCH64:
- arch = vintf::Arch::ARCH_64; break;
- case lshal::ARCH_BOTH:
- arch = vintf::Arch::ARCH_32_64; break;
- case lshal::ARCH_UNKNOWN: // fallthrough
- default:
- err() << "Warning: '" << fqName.package()
- << "' doesn't have bitness info, assuming 32+64." << std::endl;
- arch = vintf::Arch::ARCH_32_64;
- }
- } else {
- err() << "Warning: '" << entry.transport << "' is not a valid transport." << std::endl;
- continue;
- }
-
- bool done = false;
- for (vintf::ManifestHal *hal : manifest.getHals(fqName.package())) {
- if (hal->transport() != transport) {
- if (transport != vintf::Transport::PASSTHROUGH) {
- err() << "Fatal: should not reach here. Generated result may be wrong for '"
- << hal->name << "'."
- << std::endl;
- }
- done = true;
- break;
- }
- if (findAndBumpVersion(hal, version)) {
- if (&table != &mImplementationsTable) {
- hal->insertLegacyInstance(interfaceName, instanceName);
- }
- hal->transportArch.arch |= arch;
- done = true;
- break;
- }
- }
- if (done) {
- continue; // to next TableEntry
- }
- vintf::ManifestHal manifestHal{
- vintf::HalFormat::HIDL,
- std::string{fqName.package()},
- {version},
- {transport, arch},
- {}};
- if (&table != &mImplementationsTable) {
- manifestHal.insertLegacyInstance(interfaceName, instanceName);
- }
- if (!manifest.add(std::move(manifestHal))) {
- err() << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
- }
- }
- });
out << "<!-- " << std::endl
- << " This is a skeleton " << manifest.type() << " manifest. Notes: " << std::endl
- << INIT_VINTF_NOTES
- << "-->" << std::endl;
- out << vintf::gHalManifestConverter(manifest, vintf::SerializeFlag::HALS_NO_FQNAME);
+ << " This is a skeleton " << manifest.type() << " manifest. Notes: " << std::endl
+ << INIT_VINTF_NOTES;
+ if (!error.empty()) {
+ out << std::endl << " The following HALs are not added; see warnings." << std::endl;
+ for (const auto& e : error) {
+ out << " " << e << std::endl;
+ }
+ }
+ if (!passthrough.empty()) {
+ out << std::endl
+ << " The following HALs are passthrough and no interface or instance " << std::endl
+ << " names can be inferred." << std::endl;
+ for (const auto& e : passthrough) {
+ out << " " << e << std::endl;
+ }
+ }
+ out << "-->" << std::endl;
+ out << vintf::gHalManifestConverter(manifest, vintf::SerializeFlag::HALS_ONLY);
}
std::string ListCommand::INIT_VINTF_NOTES{
- " 1. If a HAL is supported in both hwbinder and passthrough transport, \n"
+ " 1. If a HAL is supported in both hwbinder and passthrough transport,\n"
" only hwbinder is shown.\n"
" 2. It is likely that HALs in passthrough transport does not have\n"
" <interface> declared; users will have to write them by hand.\n"
" 3. A HAL with lower minor version can be overridden by a HAL with\n"
" higher minor version if they have the same name and major version.\n"
+ " 4. This output is intended for launch devices.\n"
+ " Upgrading devices should not use this tool to generate device\n"
+ " manifest and replace the existing manifest directly, but should\n"
+ " edit the existing manifest manually.\n"
+ " Specifically, devices which launched at Android O-MR1 or earlier\n"
+ " should not use the 'fqname' format for required HAL entries and\n"
+ " should instead use the legacy package, name, instance-name format\n"
+ " until they are updated.\n"
};
-static Architecture fromBaseArchitecture(::android::hidl::base::V1_0::DebugInfo::Architecture a) {
+static vintf::Arch fromBaseArchitecture(::android::hidl::base::V1_0::DebugInfo::Architecture a) {
switch (a) {
case ::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT:
- return ARCH64;
+ return vintf::Arch::ARCH_64;
case ::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT:
- return ARCH32;
+ return vintf::Arch::ARCH_32;
case ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN: // fallthrough
default:
- return ARCH_UNKNOWN;
+ return vintf::Arch::ARCH_EMPTY;
}
}
@@ -499,6 +570,8 @@
}
Status ListCommand::fetchAllLibraries(const sp<IServiceManager> &manager) {
+ if (!shouldReportHalType(HalType::PASSTHROUGH_LIBRARIES)) { return OK; }
+
using namespace ::android::hardware;
using namespace ::android::hidl::manager::V1_0;
using namespace ::android::hidl::base::V1_0;
@@ -510,7 +583,7 @@
std::string{info.instanceName.c_str()};
entries.emplace(interfaceName, TableEntry{
.interfaceName = interfaceName,
- .transport = "passthrough",
+ .transport = vintf::Transport::PASSTHROUGH,
.clientPids = info.clientPids,
}).first->second.arch |= fromBaseArchitecture(info.arch);
}
@@ -527,6 +600,8 @@
}
Status ListCommand::fetchPassthrough(const sp<IServiceManager> &manager) {
+ if (!shouldReportHalType(HalType::PASSTHROUGH_CLIENTS)) { return OK; }
+
using namespace ::android::hardware;
using namespace ::android::hardware::details;
using namespace ::android::hidl::manager::V1_0;
@@ -540,7 +615,7 @@
.interfaceName =
std::string{info.interfaceName.c_str()} + "/" +
std::string{info.instanceName.c_str()},
- .transport = "passthrough",
+ .transport = vintf::Transport::PASSTHROUGH,
.serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID,
.clientPids = info.clientPids,
.arch = fromBaseArchitecture(info.arch)
@@ -556,8 +631,11 @@
}
Status ListCommand::fetchBinderized(const sp<IServiceManager> &manager) {
- const std::string mode = "hwbinder";
+ using vintf::operator<<;
+ if (!shouldReportHalType(HalType::BINDERIZED_SERVICES)) { return OK; }
+
+ const vintf::Transport mode = vintf::Transport::HWBINDER;
hidl_vec<hidl_string> fqInstanceNames;
// copying out for timeoutIPC
auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &names) {
@@ -721,7 +799,7 @@
mOptions.push_back({'l', "released", no_argument, v++, [](ListCommand* thiz, const char*) {
thiz->mSelectedColumns.push_back(TableColumnType::RELEASED);
return OK;
- }, "print the 'is released?' column\n(Y=released, empty=unreleased or unknown)"});
+ }, "print the 'is released?' column\n(Y=released, N=unreleased, ?=unknown)"});
mOptions.push_back({'t', "transport", no_argument, v++, [](ListCommand* thiz, const char*) {
thiz->mSelectedColumns.push_back(TableColumnType::TRANSPORT);
return OK;
@@ -761,6 +839,15 @@
}, "Emit debug info from\nIBase::debug with empty options. Cannot be used with --neat.\n"
"Writes to specified file if 'arg' is provided, otherwise stdout."});
+ mOptions.push_back({'V', "vintf", no_argument, v++, [](ListCommand* thiz, const char*) {
+ thiz->mSelectedColumns.push_back(TableColumnType::VINTF);
+ return OK;
+ }, "print VINTF info. This column contains a comma-separated list of:\n"
+ " - DM: device manifest\n"
+ " - DC: device compatibility matrix\n"
+ " - FM: framework manifest\n"
+ " - FC: framework compatibility matrix"});
+
// long options without short alternatives
mOptions.push_back({'\0', "init-vintf", no_argument, v++, [](ListCommand* thiz, const char* arg) {
thiz->mVintf = true;
@@ -791,6 +878,42 @@
thiz->mNeat = true;
return OK;
}, "output is machine parsable (no explanatory text).\nCannot be used with --debug."});
+ mOptions.push_back({'\0', "types", required_argument, v++, [](ListCommand* thiz, const char* arg) {
+ if (!arg) { return USAGE; }
+
+ static const std::map<std::string, HalType> kHalTypeMap {
+ {"binderized", HalType::BINDERIZED_SERVICES},
+ {"b", HalType::BINDERIZED_SERVICES},
+ {"passthrough_clients", HalType::PASSTHROUGH_CLIENTS},
+ {"c", HalType::PASSTHROUGH_CLIENTS},
+ {"passthrough_libs", HalType::PASSTHROUGH_LIBRARIES},
+ {"l", HalType::PASSTHROUGH_LIBRARIES}
+ };
+
+ std::vector<std::string> halTypesArgs = split(std::string(arg), ',');
+ for (const auto& halTypeArg : halTypesArgs) {
+ if (halTypeArg.empty()) continue;
+
+ const auto& halTypeIter = kHalTypeMap.find(halTypeArg);
+ if (halTypeIter == kHalTypeMap.end()) {
+
+ thiz->err() << "Unrecognized HAL type: " << halTypeArg << std::endl;
+ return USAGE;
+ }
+
+ // Append unique (non-repeated) HAL types to the reporting list
+ HalType halType = halTypeIter->second;
+ if (std::find(thiz->mListTypes.begin(), thiz->mListTypes.end(), halType) ==
+ thiz->mListTypes.end()) {
+ thiz->mListTypes.push_back(halType);
+ }
+ }
+
+ if (thiz->mListTypes.empty()) { return USAGE; }
+ return OK;
+ }, "comma-separated list of one or more HAL types.\nThe output is restricted to the selected "
+ "association(s). Valid options\nare: (b|binderized), (c|passthrough_clients), and (l|"
+ "passthrough_libs).\nBy default, lists all available HALs."});
}
// Create 'longopts' argument to getopt_long. Caller is responsible for maintaining
@@ -829,6 +952,7 @@
}
Status ListCommand::parseArgs(const Arg &arg) {
+ mListTypes.clear();
if (mOptions.empty()) {
registerAllOptions();
@@ -901,6 +1025,12 @@
}
}
+ // By default, list all HAL types
+ if (mListTypes.empty()) {
+ mListTypes = {HalType::BINDERIZED_SERVICES, HalType::PASSTHROUGH_CLIENTS,
+ HalType::PASSTHROUGH_LIBRARIES};
+ }
+
forEachTable([this] (Table& table) {
table.setSelectedColumns(this->mSelectedColumns);
});
@@ -919,22 +1049,6 @@
return status;
}
-static std::vector<std::string> splitString(const std::string &s, char c) {
- std::vector<std::string> components;
-
- size_t startPos = 0;
- size_t matchPos;
- while ((matchPos = s.find(c, startPos)) != std::string::npos) {
- components.push_back(s.substr(startPos, matchPos - startPos));
- startPos = matchPos + 1;
- }
-
- if (startPos <= s.length()) {
- components.push_back(s.substr(startPos));
- }
- return components;
-}
-
const std::string& ListCommand::RegisteredOption::getHelpMessageForArgument() const {
static const std::string empty{};
static const std::string optional{"[=<arg>]"};
@@ -970,7 +1084,7 @@
if (!e.longOption.empty())
err() << "--" << e.longOption << e.getHelpMessageForArgument();
err() << ": ";
- std::vector<std::string> lines = splitString(e.help, '\n');
+ std::vector<std::string> lines = split(e.help, '\n');
for (const auto& line : lines) {
if (&line != &lines.front())
err() << " ";
diff --git a/cmds/lshal/ListCommand.h b/cmds/lshal/ListCommand.h
index 1e85ea0..87d93b5 100644
--- a/cmds/lshal/ListCommand.h
+++ b/cmds/lshal/ListCommand.h
@@ -26,7 +26,9 @@
#include <android-base/macros.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
-#include <hidl-util/FQName.h>
+#include <hidl-util/FqInstance.h>
+#include <vintf/HalManifest.h>
+#include <vintf/VintfObject.h>
#include "Command.h"
#include "NullableOStream.h"
@@ -45,6 +47,12 @@
uint32_t threadCount; // number of threads total
};
+enum class HalType {
+ BINDERIZED_SERVICES = 0,
+ PASSTHROUGH_CLIENTS,
+ PASSTHROUGH_LIBRARIES
+};
+
class ListCommand : public Command {
public:
ListCommand(Lshal &lshal) : Command(lshal) {}
@@ -80,7 +88,9 @@
protected:
Status parseArgs(const Arg &arg);
+ // Retrieve first-hand information
Status fetch();
+ // Retrieve derived information base on existing table
virtual void postprocess();
Status dump();
void putEntry(TableEntrySource source, TableEntry &&entry);
@@ -113,7 +123,14 @@
void removeDeadProcesses(Pids *pids);
virtual Partition getPartition(pid_t pid);
- Partition resolvePartition(Partition processPartition, const FQName& fqName) const;
+ Partition resolvePartition(Partition processPartition, const FqInstance &fqInstance) const;
+
+ VintfInfo getVintfInfo(const std::string &fqInstanceName, vintf::TransportArch ta) const;
+ // Allow to mock these functions for testing.
+ virtual std::shared_ptr<const vintf::HalManifest> getDeviceManifest() const;
+ virtual std::shared_ptr<const vintf::CompatibilityMatrix> getDeviceMatrix() const;
+ virtual std::shared_ptr<const vintf::HalManifest> getFrameworkManifest() const;
+ virtual std::shared_ptr<const vintf::CompatibilityMatrix> getFrameworkMatrix() const;
void forEachTable(const std::function<void(Table &)> &f);
void forEachTable(const std::function<void(const Table &)> &f) const;
@@ -123,6 +140,13 @@
void registerAllOptions();
+ // helper functions to dumpVintf.
+ bool addEntryWithInstance(const TableEntry &entry, vintf::HalManifest *manifest) const;
+ bool addEntryWithoutInstance(const TableEntry &entry, const vintf::HalManifest *manifest) const;
+
+ // Helper function. Whether to list entries corresponding to a given HAL type.
+ bool shouldReportHalType(const HalType &type) const;
+
Table mServicesTable{};
Table mPassthroughRefTable{};
Table mImplementationsTable{};
@@ -139,6 +163,10 @@
// If true, explanatory text are not emitted.
bool mNeat = false;
+ // Type(s) of HAL associations to list. By default, report all.
+ std::vector<HalType> mListTypes{HalType::BINDERIZED_SERVICES, HalType::PASSTHROUGH_CLIENTS,
+ HalType::PASSTHROUGH_LIBRARIES};
+
// If an entry does not exist, need to ask /proc/{pid}/cmdline to get it.
// If an entry exist but is an empty string, process might have died.
// If an entry exist and not empty, it contains the cached content of /proc/{pid}/cmdline.
diff --git a/cmds/lshal/PipeRelay.cpp b/cmds/lshal/PipeRelay.cpp
index fc40749..3828bbf 100644
--- a/cmds/lshal/PipeRelay.cpp
+++ b/cmds/lshal/PipeRelay.cpp
@@ -16,7 +16,6 @@
#include "PipeRelay.h"
-#include <sys/socket.h>
#include <utils/Thread.h>
namespace android {
@@ -58,7 +57,7 @@
PipeRelay::PipeRelay(std::ostream &os)
: mInitCheck(NO_INIT) {
- int res = socketpair(AF_UNIX, SOCK_STREAM, 0 /* protocol */, mFds);
+ int res = pipe(mFds);
if (res < 0) {
mInitCheck = -errno;
@@ -77,20 +76,13 @@
}
PipeRelay::~PipeRelay() {
- if (mFds[1] >= 0) {
- shutdown(mFds[1], SHUT_WR);
- }
-
- if (mFds[0] >= 0) {
- shutdown(mFds[0], SHUT_RD);
- }
+ CloseFd(&mFds[1]);
if (mThread != NULL) {
mThread->join();
mThread.clear();
}
- CloseFd(&mFds[1]);
CloseFd(&mFds[0]);
}
diff --git a/cmds/lshal/TableEntry.cpp b/cmds/lshal/TableEntry.cpp
index e8792a4..4ad3e92 100644
--- a/cmds/lshal/TableEntry.cpp
+++ b/cmds/lshal/TableEntry.cpp
@@ -16,7 +16,11 @@
#define LOG_TAG "lshal"
#include <android-base/logging.h>
+#include <map>
+
+#include <android-base/strings.h>
#include <hidl-hash/Hash.h>
+#include <vintf/parse_string.h>
#include "TableEntry.h"
@@ -26,19 +30,19 @@
namespace android {
namespace lshal {
-static const std::string &getArchString(Architecture arch) {
+static const std::string &getArchString(vintf::Arch arch) {
static const std::string sStr64 = "64";
static const std::string sStr32 = "32";
static const std::string sStrBoth = "32+64";
- static const std::string sStrUnknown = "";
+ static const std::string sStrUnknown = "?";
switch (arch) {
- case ARCH64:
+ case vintf::Arch::ARCH_64:
return sStr64;
- case ARCH32:
+ case vintf::Arch::ARCH_32:
return sStr32;
- case ARCH_BOTH:
+ case vintf::Arch::ARCH_32_64:
return sStrBoth;
- case ARCH_UNKNOWN: // fall through
+ case vintf::Arch::ARCH_EMPTY: // fall through
default:
return sStrUnknown;
}
@@ -57,6 +61,7 @@
case TableColumnType::THREADS: return "Thread Use";
case TableColumnType::RELEASED: return "R";
case TableColumnType::HASH: return "Hash";
+ case TableColumnType::VINTF: return "VINTF";
default:
LOG(FATAL) << __func__ << "Should not reach here. " << static_cast<int>(type);
return "";
@@ -68,7 +73,7 @@
case TableColumnType::INTERFACE_NAME:
return interfaceName;
case TableColumnType::TRANSPORT:
- return transport;
+ return vintf::to_string(transport);
case TableColumnType::SERVER_PID:
return serverPid == NO_PID ? "N/A" : std::to_string(serverPid);
case TableColumnType::SERVER_CMD:
@@ -87,6 +92,8 @@
return isReleased();
case TableColumnType::HASH:
return hash;
+ case TableColumnType::VINTF:
+ return getVintfInfo();
default:
LOG(FATAL) << __func__ << "Should not reach here. " << static_cast<int>(type);
return "";
@@ -96,12 +103,32 @@
std::string TableEntry::isReleased() const {
static const std::string unreleased = Hash::hexString(Hash::kEmptyHash);
- if (hash.empty() || hash == unreleased) {
- return " "; // unknown or unreleased
+ if (hash.empty()) {
+ return "?";
+ }
+ if (hash == unreleased) {
+ return "N"; // unknown or unreleased
}
return "Y"; // released
}
+std::string TableEntry::getVintfInfo() const {
+ static const std::map<VintfInfo, std::string> values{
+ {DEVICE_MANIFEST, "DM"},
+ {DEVICE_MATRIX, "DC"},
+ {FRAMEWORK_MANIFEST, "FM"},
+ {FRAMEWORK_MATRIX, "FC"},
+ };
+ std::vector<std::string> ret;
+ for (const auto& pair : values) {
+ if (vintfInfo & pair.first) {
+ ret.push_back(pair.second);
+ }
+ }
+ auto joined = base::Join(ret, ',');
+ return joined.empty() ? "X" : joined;
+}
+
TextTable Table::createTextTable(bool neat,
const std::function<std::string(const std::string&)>& emitDebugInfo) const {
@@ -152,6 +179,7 @@
}
std::string TableEntry::to_string() const {
+ using vintf::operator<<;
std::stringstream ss;
ss << "name=" << interfaceName << ";transport=" << transport << ";thread=" << getThreadUsage()
<< ";server=" << serverPid
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 24ea438..c9a6a23 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -24,6 +24,8 @@
#include <iostream>
#include <procpartition/procpartition.h>
+#include <vintf/Arch.h>
+#include <vintf/Transport.h>
#include "TextTable.h"
@@ -40,14 +42,6 @@
};
using TableEntrySource = unsigned int;
-enum : unsigned int {
- ARCH_UNKNOWN = 0,
- ARCH32 = 1 << 0,
- ARCH64 = 1 << 1,
- ARCH_BOTH = ARCH32 | ARCH64
-};
-using Architecture = unsigned int;
-
enum class TableColumnType : unsigned int {
INTERFACE_NAME,
TRANSPORT,
@@ -60,8 +54,18 @@
THREADS,
RELEASED,
HASH,
+ VINTF,
};
+enum : unsigned int {
+ VINTF_INFO_EMPTY = 0,
+ DEVICE_MANIFEST = 1 << 0,
+ DEVICE_MATRIX = 1 << 1,
+ FRAMEWORK_MANIFEST = 1 << 2,
+ FRAMEWORK_MATRIX = 1 << 3,
+};
+using VintfInfo = unsigned int;
+
enum {
NO_PID = -1,
NO_PTR = 0
@@ -69,7 +73,7 @@
struct TableEntry {
std::string interfaceName{};
- std::string transport{};
+ vintf::Transport transport{vintf::Transport::EMPTY};
int32_t serverPid{NO_PID};
uint32_t threadUsage{0};
uint32_t threadCount{0};
@@ -77,10 +81,11 @@
uint64_t serverObjectAddress{NO_PTR};
Pids clientPids{};
std::vector<std::string> clientCmdlines{};
- Architecture arch{ARCH_UNKNOWN};
+ vintf::Arch arch{vintf::Arch::ARCH_EMPTY};
// empty: unknown, all zeros: unreleased, otherwise: released
std::string hash{};
Partition partition{Partition::UNKNOWN};
+ VintfInfo vintfInfo{VINTF_INFO_EMPTY};
static bool sortByInterfaceName(const TableEntry &a, const TableEntry &b) {
return a.interfaceName < b.interfaceName;
@@ -99,6 +104,8 @@
std::string isReleased() const;
+ std::string getVintfInfo() const;
+
std::string getField(TableColumnType type) const;
bool operator==(const TableEntry& other) const;
diff --git a/cmds/lshal/libprocpartition/procpartition.cpp b/cmds/lshal/libprocpartition/procpartition.cpp
index 8ca458a..9645f3a 100644
--- a/cmds/lshal/libprocpartition/procpartition.cpp
+++ b/cmds/lshal/libprocpartition/procpartition.cpp
@@ -50,7 +50,7 @@
false /* follow symlinks */)) {
return "";
}
- return content;
+ return std::string{content.c_str()};
}
Partition parsePartition(const std::string& s) {
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index 4fa941e..501c04d 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -44,6 +44,13 @@
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
+using android::vintf::Arch;
+using android::vintf::CompatibilityMatrix;
+using android::vintf::gCompatibilityMatrixConverter;
+using android::vintf::gHalManifestConverter;
+using android::vintf::HalManifest;
+using android::vintf::Transport;
+using android::vintf::VintfObject;
using InstanceDebugInfo = IServiceManager::InstanceDebugInfo;
@@ -207,6 +214,11 @@
MOCK_CONST_METHOD2(getPidInfo, bool(pid_t, PidInfo*));
MOCK_CONST_METHOD1(parseCmdline, std::string(pid_t));
MOCK_METHOD1(getPartition, Partition(pid_t));
+
+ MOCK_CONST_METHOD0(getDeviceManifest, std::shared_ptr<const vintf::HalManifest>());
+ MOCK_CONST_METHOD0(getDeviceMatrix, std::shared_ptr<const vintf::CompatibilityMatrix>());
+ MOCK_CONST_METHOD0(getFrameworkManifest, std::shared_ptr<const vintf::HalManifest>());
+ MOCK_CONST_METHOD0(getFrameworkMatrix, std::shared_ptr<const vintf::CompatibilityMatrix>());
};
class ListParseArgsTest : public ::testing::Test {
@@ -335,6 +347,15 @@
});
}));
ON_CALL(*mockList, getPartition(_)).WillByDefault(Return(Partition::VENDOR));
+
+ ON_CALL(*mockList, getDeviceManifest())
+ .WillByDefault(Return(VintfObject::GetDeviceHalManifest()));
+ ON_CALL(*mockList, getDeviceMatrix())
+ .WillByDefault(Return(VintfObject::GetDeviceCompatibilityMatrix()));
+ ON_CALL(*mockList, getFrameworkManifest())
+ .WillByDefault(Return(VintfObject::GetFrameworkHalManifest()));
+ ON_CALL(*mockList, getFrameworkMatrix())
+ .WillByDefault(Return(VintfObject::GetFrameworkCompatibilityMatrix()));
}
void initMockServiceManager() {
@@ -389,25 +410,28 @@
TEST_F(ListTest, Fetch) {
EXPECT_EQ(0u, mockList->fetch());
- std::array<std::string, 6> transports{{"hwbinder", "hwbinder", "passthrough",
- "passthrough", "passthrough", "passthrough"}};
- std::array<Architecture, 6> archs{{ARCH64, ARCH64, ARCH32, ARCH32, ARCH32, ARCH32}};
+ vintf::TransportArch hwbinder{Transport::HWBINDER, Arch::ARCH_64};
+ vintf::TransportArch passthrough{Transport::PASSTHROUGH, Arch::ARCH_32};
+ std::array<vintf::TransportArch, 6> transportArchs{{hwbinder, hwbinder, passthrough,
+ passthrough, passthrough, passthrough}};
int id = 1;
mockList->forEachTable([&](const Table& table) {
ASSERT_EQ(2u, table.size());
for (const auto& entry : table) {
- const auto& transport = transports[id - 1];
+ auto transport = transportArchs.at(id - 1).transport;
TableEntry expected{
.interfaceName = getFqInstanceName(id),
.transport = transport,
- .serverPid = transport == "hwbinder" ? id : NO_PID,
- .threadUsage = transport == "hwbinder" ? getPidInfoFromId(id).threadUsage : 0,
- .threadCount = transport == "hwbinder" ? getPidInfoFromId(id).threadCount : 0,
+ .serverPid = transport == Transport::HWBINDER ? id : NO_PID,
+ .threadUsage =
+ transport == Transport::HWBINDER ? getPidInfoFromId(id).threadUsage : 0,
+ .threadCount =
+ transport == Transport::HWBINDER ? getPidInfoFromId(id).threadCount : 0,
.serverCmdline = {},
- .serverObjectAddress = transport == "hwbinder" ? getPtr(id) : NO_PTR,
+ .serverObjectAddress = transport == Transport::HWBINDER ? getPtr(id) : NO_PTR,
.clientPids = getClients(id),
.clientCmdlines = {},
- .arch = archs[id - 1],
+ .arch = transportArchs.at(id - 1).arch,
};
EXPECT_EQ(expected, entry) << expected.to_string() << " vs. " << entry.to_string();
@@ -418,62 +442,35 @@
}
TEST_F(ListTest, DumpVintf) {
- const std::string expected =
- "<!-- \n"
- " This is a skeleton device manifest. Notes: \n" + ListCommand::INIT_VINTF_NOTES +
- "-->\n"
- "<manifest version=\"1.0\" type=\"device\">\n"
- " <hal format=\"hidl\">\n"
- " <name>a.h.foo1</name>\n"
- " <transport>hwbinder</transport>\n"
- " <version>1.0</version>\n"
- " <interface>\n"
- " <name>IFoo</name>\n"
- " <instance>1</instance>\n"
- " </interface>\n"
- " </hal>\n"
- " <hal format=\"hidl\">\n"
- " <name>a.h.foo2</name>\n"
- " <transport>hwbinder</transport>\n"
- " <version>2.0</version>\n"
- " <interface>\n"
- " <name>IFoo</name>\n"
- " <instance>2</instance>\n"
- " </interface>\n"
- " </hal>\n"
- " <hal format=\"hidl\">\n"
- " <name>a.h.foo3</name>\n"
- " <transport arch=\"32\">passthrough</transport>\n"
- " <version>3.0</version>\n"
- " <interface>\n"
- " <name>IFoo</name>\n"
- " <instance>3</instance>\n"
- " </interface>\n"
- " </hal>\n"
- " <hal format=\"hidl\">\n"
- " <name>a.h.foo4</name>\n"
- " <transport arch=\"32\">passthrough</transport>\n"
- " <version>4.0</version>\n"
- " <interface>\n"
- " <name>IFoo</name>\n"
- " <instance>4</instance>\n"
- " </interface>\n"
- " </hal>\n"
- " <hal format=\"hidl\">\n"
- " <name>a.h.foo5</name>\n"
- " <transport arch=\"32\">passthrough</transport>\n"
- " <version>5.0</version>\n"
- " </hal>\n"
- " <hal format=\"hidl\">\n"
- " <name>a.h.foo6</name>\n"
- " <transport arch=\"32\">passthrough</transport>\n"
- " <version>6.0</version>\n"
- " </hal>\n"
- "</manifest>\n";
+ const std::string expected = "<manifest version=\"1.0\" type=\"device\">\n"
+ " <hal format=\"hidl\">\n"
+ " <name>a.h.foo1</name>\n"
+ " <transport>hwbinder</transport>\n"
+ " <fqname>@1.0::IFoo/1</fqname>\n"
+ " </hal>\n"
+ " <hal format=\"hidl\">\n"
+ " <name>a.h.foo2</name>\n"
+ " <transport>hwbinder</transport>\n"
+ " <fqname>@2.0::IFoo/2</fqname>\n"
+ " </hal>\n"
+ " <hal format=\"hidl\">\n"
+ " <name>a.h.foo3</name>\n"
+ " <transport arch=\"32\">passthrough</transport>\n"
+ " <fqname>@3.0::IFoo/3</fqname>\n"
+ " </hal>\n"
+ " <hal format=\"hidl\">\n"
+ " <name>a.h.foo4</name>\n"
+ " <transport arch=\"32\">passthrough</transport>\n"
+ " <fqname>@4.0::IFoo/4</fqname>\n"
+ " </hal>\n"
+ "</manifest>";
optind = 1; // mimic Lshal::parseArg()
EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--init-vintf"})));
- EXPECT_EQ(expected, out.str());
+ auto output = out.str();
+ EXPECT_THAT(output, HasSubstr(expected));
+ EXPECT_THAT(output, HasSubstr("a.h.foo5@5.0::IFoo/5"));
+ EXPECT_THAT(output, HasSubstr("a.h.foo6@6.0::IFoo/6"));
EXPECT_EQ("", err.str());
vintf::HalManifest m;
@@ -487,18 +484,18 @@
const std::string expected =
"[fake description 0]\n"
"R Interface Thread Use Server Clients\n"
- " a.h.foo1@1.0::IFoo/1 11/21 1 2 4\n"
+ "N a.h.foo1@1.0::IFoo/1 11/21 1 2 4\n"
"Y a.h.foo2@2.0::IFoo/2 12/22 2 3 5\n"
"\n"
"[fake description 1]\n"
"R Interface Thread Use Server Clients\n"
- " a.h.foo3@3.0::IFoo/3 N/A N/A 4 6\n"
- " a.h.foo4@4.0::IFoo/4 N/A N/A 5 7\n"
+ "? a.h.foo3@3.0::IFoo/3 N/A N/A 4 6\n"
+ "? a.h.foo4@4.0::IFoo/4 N/A N/A 5 7\n"
"\n"
"[fake description 2]\n"
"R Interface Thread Use Server Clients\n"
- " a.h.foo5@5.0::IFoo/5 N/A N/A 6 8\n"
- " a.h.foo6@6.0::IFoo/6 N/A N/A 7 9\n"
+ "? a.h.foo5@5.0::IFoo/5 N/A N/A 6 8\n"
+ "? a.h.foo6@6.0::IFoo/6 N/A N/A 7 9\n"
"\n";
optind = 1; // mimic Lshal::parseArg()
@@ -511,18 +508,18 @@
const std::string expected =
"[fake description 0]\n"
"Interface R Hash\n"
- "a.h.foo1@1.0::IFoo/1 0000000000000000000000000000000000000000000000000000000000000000\n"
+ "a.h.foo1@1.0::IFoo/1 N 0000000000000000000000000000000000000000000000000000000000000000\n"
"a.h.foo2@2.0::IFoo/2 Y 0202020202020202020202020202020202020202020202020202020202020202\n"
"\n"
"[fake description 1]\n"
"Interface R Hash\n"
- "a.h.foo3@3.0::IFoo/3 \n"
- "a.h.foo4@4.0::IFoo/4 \n"
+ "a.h.foo3@3.0::IFoo/3 ? \n"
+ "a.h.foo4@4.0::IFoo/4 ? \n"
"\n"
"[fake description 2]\n"
"Interface R Hash\n"
- "a.h.foo5@5.0::IFoo/5 \n"
- "a.h.foo6@6.0::IFoo/6 \n"
+ "a.h.foo5@5.0::IFoo/5 ? \n"
+ "a.h.foo6@6.0::IFoo/6 ? \n"
"\n";
optind = 1; // mimic Lshal::parseArg()
@@ -594,6 +591,171 @@
EXPECT_EQ("", err.str());
}
+TEST_F(ListTest, DumpSingleHalType) {
+ const std::string expected =
+ "[fake description 0]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo1@1.0::IFoo/1 hwbinder 64 11/21 1 0000000000002711 2 4\n"
+ "a.h.foo2@2.0::IFoo/2 hwbinder 64 12/22 2 0000000000002712 3 5\n"
+ "\n";
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=binderized"})));
+ EXPECT_EQ(expected, out.str());
+ EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpReorderedHalTypes) {
+ const std::string expected =
+ "[fake description 0]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo3@3.0::IFoo/3 passthrough 32 N/A N/A N/A 4 6\n"
+ "a.h.foo4@4.0::IFoo/4 passthrough 32 N/A N/A N/A 5 7\n"
+ "\n"
+ "[fake description 1]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo5@5.0::IFoo/5 passthrough 32 N/A N/A N/A 6 8\n"
+ "a.h.foo6@6.0::IFoo/6 passthrough 32 N/A N/A N/A 7 9\n"
+ "\n"
+ "[fake description 2]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo1@1.0::IFoo/1 hwbinder 64 11/21 1 0000000000002711 2 4\n"
+ "a.h.foo2@2.0::IFoo/2 hwbinder 64 12/22 2 0000000000002712 3 5\n"
+ "\n";
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=passthrough_clients",
+ "--types=passthrough_libs", "--types=binderized"})));
+ EXPECT_EQ(expected, out.str());
+ EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpAbbreviatedHalTypes) {
+ const std::string expected =
+ "[fake description 0]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo3@3.0::IFoo/3 passthrough 32 N/A N/A N/A 4 6\n"
+ "a.h.foo4@4.0::IFoo/4 passthrough 32 N/A N/A N/A 5 7\n"
+ "\n"
+ "[fake description 1]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo5@5.0::IFoo/5 passthrough 32 N/A N/A N/A 6 8\n"
+ "a.h.foo6@6.0::IFoo/6 passthrough 32 N/A N/A N/A 7 9\n"
+ "\n";
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,l"})));
+ EXPECT_EQ(expected, out.str());
+ EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, DumpEmptyAndDuplicateHalTypes) {
+ const std::string expected =
+ "[fake description 0]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo3@3.0::IFoo/3 passthrough 32 N/A N/A N/A 4 6\n"
+ "a.h.foo4@4.0::IFoo/4 passthrough 32 N/A N/A N/A 5 7\n"
+ "\n"
+ "[fake description 1]\n"
+ "Interface Transport Arch Thread Use Server PTR Clients\n"
+ "a.h.foo5@5.0::IFoo/5 passthrough 32 N/A N/A N/A 6 8\n"
+ "a.h.foo6@6.0::IFoo/6 passthrough 32 N/A N/A N/A 7 9\n"
+ "\n";
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,l,,,l,l,c,",
+ "--types=passthrough_libs,passthrough_clients"})));
+ EXPECT_EQ(expected, out.str());
+ EXPECT_EQ("", err.str());
+}
+
+TEST_F(ListTest, UnknownHalType) {
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(1u, mockList->main(createArg({"lshal", "-itrepac", "--types=c,a"})));
+ EXPECT_THAT(err.str(), HasSubstr("Unrecognized HAL type: a"));
+}
+
+TEST_F(ListTest, Vintf) {
+ std::string deviceManifestXml =
+ "<manifest version=\"1.0\" type=\"device\">\n"
+ " <hal>\n"
+ " <name>a.h.foo1</name>\n"
+ " <transport>hwbinder</transport>\n"
+ " <fqname>@1.0::IFoo/1</fqname>\n"
+ " </hal>\n"
+ " <hal>\n"
+ " <name>a.h.foo3</name>\n"
+ " <transport arch=\"32+64\">passthrough</transport>\n"
+ " <fqname>@3.0::IFoo/3</fqname>\n"
+ " </hal>\n"
+ "</manifest>\n";
+ std::string frameworkManifestXml =
+ "<manifest version=\"1.0\" type=\"framework\">\n"
+ " <hal>\n"
+ " <name>a.h.foo5</name>\n"
+ " <transport arch=\"32\">passthrough</transport>\n"
+ " <fqname>@5.0::IFoo/5</fqname>\n"
+ " </hal>\n"
+ "</manifest>\n";
+ std::string deviceMatrixXml =
+ "<compatibility-matrix version=\"1.0\" type=\"device\">\n"
+ " <hal>\n"
+ " <name>a.h.foo5</name>\n"
+ " <version>5.0</version>\n"
+ " <interface>\n"
+ " <name>IFoo</name>\n"
+ " <instance>5</instance>\n"
+ " </interface>\n"
+ " </hal>\n"
+ "</compatibility-matrix>\n";
+ std::string frameworkMatrixXml =
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
+ " <hal>\n"
+ " <name>a.h.foo1</name>\n"
+ " <version>1.0</version>\n"
+ " <interface>\n"
+ " <name>IFoo</name>\n"
+ " <instance>1</instance>\n"
+ " </interface>\n"
+ " </hal>\n"
+ " <hal>\n"
+ " <name>a.h.foo3</name>\n"
+ " <version>3.0</version>\n"
+ " <interface>\n"
+ " <name>IFoo</name>\n"
+ " <instance>3</instance>\n"
+ " </interface>\n"
+ " </hal>\n"
+ "</compatibility-matrix>\n";
+
+ std::string expected = "DM,FC a.h.foo1@1.0::IFoo/1\n"
+ "X a.h.foo2@2.0::IFoo/2\n"
+ "DM,FC a.h.foo3@3.0::IFoo/3\n"
+ "X a.h.foo4@4.0::IFoo/4\n"
+ "DC,FM a.h.foo5@5.0::IFoo/5\n"
+ "X a.h.foo6@6.0::IFoo/6\n";
+
+ auto deviceManifest = std::make_shared<HalManifest>();
+ auto frameworkManifest = std::make_shared<HalManifest>();
+ auto deviceMatrix = std::make_shared<CompatibilityMatrix>();
+ auto frameworkMatrix = std::make_shared<CompatibilityMatrix>();
+
+ ASSERT_TRUE(gHalManifestConverter(deviceManifest.get(), deviceManifestXml));
+ ASSERT_TRUE(gHalManifestConverter(frameworkManifest.get(), frameworkManifestXml));
+ ASSERT_TRUE(gCompatibilityMatrixConverter(deviceMatrix.get(), deviceMatrixXml));
+ ASSERT_TRUE(gCompatibilityMatrixConverter(frameworkMatrix.get(), frameworkMatrixXml));
+
+ ON_CALL(*mockList, getDeviceManifest()).WillByDefault(Return(deviceManifest));
+ ON_CALL(*mockList, getDeviceMatrix()).WillByDefault(Return(deviceMatrix));
+ ON_CALL(*mockList, getFrameworkManifest()).WillByDefault(Return(frameworkManifest));
+ ON_CALL(*mockList, getFrameworkMatrix()).WillByDefault(Return(frameworkMatrix));
+
+ optind = 1; // mimic Lshal::parseArg()
+ EXPECT_EQ(0u, mockList->main(createArg({"lshal", "-Vi", "--neat"})));
+ EXPECT_THAT(out.str(), HasSubstr(expected));
+ EXPECT_EQ("", err.str());
+}
+
class HelpTest : public ::testing::Test {
public:
void SetUp() override {
diff --git a/cmds/rawbu/Android.bp b/cmds/rawbu/Android.bp
new file mode 100644
index 0000000..363ffc1
--- /dev/null
+++ b/cmds/rawbu/Android.bp
@@ -0,0 +1,14 @@
+// Copyright 2009 The Android Open Source Project
+
+cc_binary {
+ name: "rawbu",
+
+ srcs: ["backup.cpp"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: ["libcutils"],
+}
diff --git a/cmds/rawbu/Android.mk b/cmds/rawbu/Android.mk
deleted file mode 100644
index 9322151..0000000
--- a/cmds/rawbu/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2009 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= backup.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := libcutils libc
-
-LOCAL_MODULE:= rawbu
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
-
-include $(BUILD_EXECUTABLE)
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index 97892f8..5f2a57f 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -14,6 +14,15 @@
* limitations under the License.
*/
+/**
+ * @addtogroup Networking
+ * @{
+ */
+
+/**
+ * @file multinetwork.h
+ */
+
#ifndef ANDROID_MULTINETWORK_H
#define ANDROID_MULTINETWORK_H
@@ -104,3 +113,5 @@
__END_DECLS
#endif // ANDROID_MULTINETWORK_H
+
+/** @} */
diff --git a/include/android/native_window_jni.h b/include/android/native_window_jni.h
index 23b39aa..082fab2 100644
--- a/include/android/native_window_jni.h
+++ b/include/android/native_window_jni.h
@@ -44,16 +44,6 @@
*/
ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
-#if __ANDROID_API__ >= 13
-/**
- * Return the ANativeWindow associated with a Java SurfaceTexture object,
- * for interacting with it through native code. This acquires a reference
- * on the ANativeWindow that is returned; be sure to use ANativeWindow_release()
- * when done with it so that it doesn't leak.
- */
-ANativeWindow* ANativeWindow_fromSurfaceTexture(JNIEnv* env, jobject surfaceTexture);
-#endif
-
#if __ANDROID_API__ >= 26
/**
* Return a Java Surface object derived from the ANativeWindow, for interacting
diff --git a/include/android/trace.h b/include/android/trace.h
index d3b1fb6..d9e5d88 100644
--- a/include/android/trace.h
+++ b/include/android/trace.h
@@ -15,6 +15,11 @@
*/
/**
+ * @addtogroup Tracing
+ * @{
+ */
+
+/**
* @file trace.h
* @brief Writes trace events to the system trace buffer.
*
@@ -65,3 +70,5 @@
#endif
#endif // ANDROID_NATIVE_TRACE_H
+
+/** @} */
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 7c1eaaf..b8d6c78 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -36,6 +36,7 @@
vndk: {
enabled: true,
},
+ double_loadable: true,
srcs: [
"ActivityManager.cpp",
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
index c5c3fd5..df0fcae 100644
--- a/libs/binder/Static.cpp
+++ b/libs/binder/Static.cpp
@@ -75,21 +75,6 @@
Mutex gProcessMutex;
sp<ProcessState> gProcess;
-class LibBinderIPCtStatics
-{
-public:
- LibBinderIPCtStatics()
- {
- }
-
- ~LibBinderIPCtStatics()
- {
- IPCThreadState::shutdown();
- }
-};
-
-static LibBinderIPCtStatics gIPCStatics;
-
// ------------ IServiceManager.cpp
Mutex gDefaultServiceManagerLock;
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index 0f1fe5b..227d0ae 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -142,7 +142,7 @@
{
return remote();
}
-
+
// ----------------------------------------------------------------------
}; // namespace android
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 73f2147..b29c1d5 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -23,6 +23,7 @@
vndk: {
enabled: true,
},
+ double_loadable: true,
clang: true,
cflags: [
@@ -72,9 +73,6 @@
],
product_variables: {
- brillo: {
- cflags: ["-DHAVE_NO_SURFACE_FLINGER"],
- },
eng: {
cppflags: [
"-UDEBUG_ONLY_CODE",
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 78cec41..32b9266 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -15,6 +15,11 @@
*/
/**
+ * @addtogroup NativeActivity Native Activity
+ * @{
+ */
+
+/**
* @file hardware_buffer.h
*/
@@ -305,3 +310,5 @@
__END_DECLS
#endif // ANDROID_HARDWARE_BUFFER_H
+
+/** @} */
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index ff9d19e..d25ad1a 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -18,6 +18,7 @@
vndk: {
enabled: true,
},
+ double_loadable: true,
clang: true,
cflags: [
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index ff53aa8..ed7ccb0b 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -109,25 +109,25 @@
return SIGNAL_TIME_INVALID;
}
- struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd);
+ struct sync_file_info* finfo = sync_file_info(mFenceFd);
if (finfo == NULL) {
- ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd.get());
+ ALOGE("sync_file_info returned NULL for fd %d", mFenceFd.get());
return SIGNAL_TIME_INVALID;
}
if (finfo->status != 1) {
- sync_fence_info_free(finfo);
+ sync_file_info_free(finfo);
return SIGNAL_TIME_PENDING;
}
- struct sync_pt_info* pinfo = NULL;
uint64_t timestamp = 0;
- while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) {
- if (pinfo->timestamp_ns > timestamp) {
- timestamp = pinfo->timestamp_ns;
+ struct sync_fence_info* pinfo = sync_get_fence_info(finfo);
+ for (size_t i = 0; i < finfo->num_fences; i++) {
+ if (pinfo[i].timestamp_ns > timestamp) {
+ timestamp = pinfo[i].timestamp_ns;
}
}
- sync_fence_info_free(finfo);
+ sync_file_info_free(finfo);
return nsecs_t(timestamp);
}
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index b92cbf3..37cf617 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -39,7 +39,7 @@
static const uint64_t valid10UsageBits = []() -> uint64_t {
using hardware::graphics::common::V1_0::BufferUsage;
uint64_t bits = 0;
- for (const auto bit : hardware::hidl_enum_iterator<BufferUsage>()) {
+ for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
bits = bits | bit;
}
// TODO(b/72323293, b/72703005): Remove these additional bits
@@ -54,7 +54,7 @@
static const uint64_t valid11UsageBits = []() -> uint64_t {
using hardware::graphics::common::V1_1::BufferUsage;
uint64_t bits = 0;
- for (const auto bit : hardware::hidl_enum_iterator<BufferUsage>()) {
+ for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
bits = bits | bit;
}
return bits;
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index 7b5ad44..69b6422 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -59,7 +59,6 @@
}
cc_test {
- tags: ["optional"],
srcs: ["buffer_hub-test.cpp"],
static_libs: ["libbufferhub"],
shared_libs: sharedLibraries,
diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
index 8ae7a0b..5089b87 100644
--- a/libs/vr/libbufferhubqueue/benchmarks/Android.bp
+++ b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
@@ -23,5 +23,4 @@
"-Werror",
],
name: "buffer_transport_benchmark",
- tags: ["optional"],
}
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index ca1e7bd..a337921 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -38,7 +38,6 @@
"-Wno-error=sign-compare", // to fix later
],
name: "buffer_hub_queue-test",
- tags: ["optional"],
}
cc_test {
@@ -55,5 +54,4 @@
"-Werror",
],
name: "buffer_hub_queue_producer-test",
- tags: ["optional"],
}
diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
index 192fb5d..9c67881 100644
--- a/libs/vr/libdisplay/Android.bp
+++ b/libs/vr/libdisplay/Android.bp
@@ -50,7 +50,6 @@
]
cc_library {
- tags: ["tests"],
srcs: sourceFiles,
cflags: ["-DLOG_TAG=\"libdisplay\"",
"-DTRACE=0",
diff --git a/libs/vr/libdvrcommon/Android.bp b/libs/vr/libdvrcommon/Android.bp
index 32b793a..e751768 100644
--- a/libs/vr/libdvrcommon/Android.bp
+++ b/libs/vr/libdvrcommon/Android.bp
@@ -59,7 +59,6 @@
cc_test {
name: "libdvrcommon_test",
- tags: ["optional"],
srcs: testFiles,
cflags: [
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 322e8a0..c511c5e 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -15,7 +15,6 @@
cc_test {
name: "SurfaceFlinger_test",
defaults: ["surfaceflinger_defaults"],
- tags: ["test"],
test_suites: ["device-tests"],
srcs: [
"Stress_test.cpp",
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index 520df2d..19af82c 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -1,7 +1,6 @@
cc_test {
name: "sffakehwc_test",
defaults: ["surfaceflinger_defaults"],
- tags: ["test"],
test_suites: ["device-tests"],
srcs: [
"FakeComposerClient.cpp",
diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp
index 0957d6a..1c8e396 100644
--- a/services/surfaceflinger/tests/hwc2/Android.bp
+++ b/services/surfaceflinger/tests/hwc2/Android.bp
@@ -15,7 +15,6 @@
cc_test {
name: "test-hwc2",
defaults: ["surfaceflinger_defaults"],
- tags: ["test"],
cflags: [
"-DEGL_EGLEXT_PROTOTYPES",
"-DGL_GLEXT_PROTOTYPES",
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 39761dd..8c268b2 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -14,7 +14,6 @@
cc_test {
name: "libsurfaceflinger_unittest",
- tags: ["test"],
defaults: ["libsurfaceflinger_defaults"],
test_suites: ["device-tests"],
srcs: [
diff --git a/services/surfaceflinger/tests/vsync/Android.bp b/services/surfaceflinger/tests/vsync/Android.bp
index d04efda..6a89945 100644
--- a/services/surfaceflinger/tests/vsync/Android.bp
+++ b/services/surfaceflinger/tests/vsync/Android.bp
@@ -15,7 +15,6 @@
cc_binary {
name: "test-vsync-events",
defaults: ["surfaceflinger_defaults"],
- tags: ["test"],
srcs: [
"vsync.cpp",
],
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
index 513fcc1..bb16c09 100644
--- a/services/vr/virtual_touchpad/Android.bp
+++ b/services/vr/virtual_touchpad/Android.bp
@@ -29,7 +29,6 @@
"-Werror",
],
name: "libvirtualtouchpad",
- tags: ["optional"],
}
// Touchpad unit tests.
@@ -60,7 +59,6 @@
],
name: "VirtualTouchpad_test",
stl: "libc++_static",
- tags: ["optional"],
}
// Service.
@@ -96,7 +94,6 @@
],
host_ldlibs: ["-llog"],
name: "virtual_touchpad",
- tags: ["optional"],
init_rc: ["virtual_touchpad.rc"],
compile_multilib: "64",
stl: "libc++_static",
@@ -129,6 +126,5 @@
],
host_ldlibs: ["-llog"],
name: "libvirtualtouchpadclient",
- tags: ["optional"],
export_include_dirs: ["include"],
}
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index d0e8346..832a8e9 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -28,7 +28,7 @@
// API version (major.minor.patch)
define VERSION_MAJOR 1
define VERSION_MINOR 1
-define VERSION_PATCH 68
+define VERSION_PATCH 76
// API limits
define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
@@ -222,7 +222,7 @@
@extension("VK_EXT_shader_subgroup_vote") define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote"
// 70
-@extension("VK_KHR_maintenance1") define VK_KHR_MAINTENANCE1_SPEC_VERSION 1
+@extension("VK_KHR_maintenance1") define VK_KHR_MAINTENANCE1_SPEC_VERSION 2
@extension("VK_KHR_maintenance1") define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
// 71
@@ -377,6 +377,10 @@
@extension("VK_KHR_variable_pointers") define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1
@extension("VK_KHR_variable_pointers") define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers"
+// 122
+@extension("VK_KHR_get_display_properties2") define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1
+@extension("VK_KHR_get_display_properties2") define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2"
+
// 123
@extension("VK_MVK_ios_surface") define VK_MVK_IOS_SURFACE_SPEC_VERSION 1
@extension("VK_MVK_ios_surface") define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
@@ -402,7 +406,7 @@
@extension("VK_EXT_debug_utils") define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils"
// 130
-@extension("VK_ANDROID_external_memory_android_hardware_buffer") define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 2
+@extension("VK_ANDROID_external_memory_android_hardware_buffer") define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3
@extension("VK_ANDROID_external_memory_android_hardware_buffer") define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
// 131
@@ -477,6 +481,10 @@
@extension("VK_EXT_validation_cache") define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1
@extension("VK_EXT_validation_cache") define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache"
+// 162
+@extension("VK_EXT_descriptor_indexing") define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
+@extension("VK_EXT_descriptor_indexing") define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+
// 165
@extension("VK_EXT_shader_viewport_index_layer") define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1
@extension("VK_EXT_shader_viewport_index_layer") define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
@@ -485,6 +493,10 @@
@extension("VK_KHR_maintenance3") define VK_KHR_MAINTENANCE3_SPEC_VERSION 1
@extension("VK_KHR_maintenance3") define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3"
+// 170
+@extension("VK_KHR_draw_indirect_count") define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
+@extension("VK_KHR_draw_indirect_count") define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count"
+
// 175
@extension("VK_EXT_global_priority") define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 1
@extension("VK_EXT_global_priority") define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority"
@@ -493,6 +505,22 @@
@extension("VK_EXT_external_memory_host") define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1
@extension("VK_EXT_external_memory_host") define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host"
+// 180
+@extension("VK_AMD_buffer_marker") define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1
+@extension("VK_AMD_buffer_marker") define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker"
+
+// 186
+@extension("VK_AMD_shader_core_properties") define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1
+@extension("VK_AMD_shader_core_properties") define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties"
+
+// 191
+@extension("VK_EXT_vertex_attribute_divisor") define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1
+@extension("VK_EXT_vertex_attribute_divisor") define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor"
+
+// 199
+@extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1
+@extension("VK_NV_shader_subgroup_partitioned") define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
+
/////////////
// Types //
/////////////
@@ -1501,6 +1529,13 @@
//@extension("VK_KHR_variable_pointers") // 121
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = 1000120000,
+ //@extension("VK_KHR_display_properties2") // 122
+ VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001,
+ VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004,
+
//@extension("VK_MVK_ios_surface") // 123
VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
@@ -1574,6 +1609,13 @@
VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
+ //@extension("VK_EXT_descriptor_indexing") // 162
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
+
//@extension("VK_KHR_maintenance3") // 169
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = 1000168000,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = 1000168001,
@@ -1585,6 +1627,13 @@
VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
+
+ //@extension("VK_AMD_shader_core_properties") // 186
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
+
+ //@extension("VK_EXT_vertex_attribute_divisor") // 191
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
}
enum VkSubpassContents {
@@ -1652,6 +1701,9 @@
//@extension("VK_KHR_external_memory") // 73
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = 0xC4641CBD, // -1000072003
+
+ //@extension("VK_EXT_descriptor_indexing") // 162
+ VK_ERROR_FRAGMENTATION_EXT = 0xc462c118, // -1000161000
}
enum VkDynamicState {
@@ -2121,6 +2173,9 @@
type VkFlags VkDescriptorPoolCreateFlags
bitfield VkDescriptorPoolCreateFlagBits {
VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
+
+ //@extension("VK_EXT_descriptor_indexing") // 162
+ VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002,
}
/// Descriptor pool reset flags
@@ -2476,6 +2531,9 @@
bitfield VkDescriptorSetLayoutCreateFlagBits {
//@extension("VK_KHR_push_descriptor") // 81
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
+
+ //@extension("VK_EXT_descriptor_indexing") // 162
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002,
}
/// Pipeline vertex input state creation flags
@@ -2581,6 +2639,9 @@
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020,
VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040,
VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080,
+
+ //@extension("VK_NV_shader_subgroup_partitioned") // 199
+ VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100,
}
/// Peer memory feature flags
@@ -3034,6 +3095,16 @@
//bitfield VkValidationCacheCreateFlagBitsEXT {
//}
+@extension("VK_EXT_descriptor_indexing") // 162
+type VkFlags VkDescriptorBindingFlagsEXT
+@extension("VK_EXT_descriptor_indexing") // 162
+bitfield VkDescriptorBindingFlagBitsEXT {
+ VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001,
+ VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002,
+ VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004,
+ VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008,
+}
+
//////////////////
// Structures //
//////////////////
@@ -4138,6 +4209,16 @@
u32 z
}
+class VkBaseOutStructure {
+ VkStructureType sType
+ void* pNext
+}
+
+class VkBaseInStructure {
+ VkStructureType sType
+ const void* pNext
+}
+
//@vulkan1_1 structures
class VkPhysicalDeviceSubgroupProperties {
@@ -5951,6 +6032,42 @@
VkBool32 variablePointers
}
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayProperties2KHR {
+ VkStructureType sType
+ void* pNext
+ VkDisplayPropertiesKHR displayProperties
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayPlaneProperties2KHR {
+ VkStructureType sType
+ void* pNext
+ VkDisplayPlanePropertiesKHR displayPlaneProperties
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayModeProperties2KHR {
+ VkStructureType sType
+ void* pNext
+ VkDisplayModePropertiesKHR displayModeProperties
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayPlaneInfo2KHR {
+ VkStructureType sType
+ const void* pNext
+ VkDisplayModeKHR mode
+ u32 planeIndex
+}
+
+@extension("VK_KHR_display_properties2") // 122
+class VkDisplayPlaneCapabilities2KHR {
+ VkStructureType sType
+ void* pNext
+ VkDisplayPlaneCapabilitiesKHR capabilities
+}
+
@extension("VK_MVK_ios_surface") // 123
class VkIOSSurfaceCreateInfoMVK {
VkStructureType sType
@@ -5991,7 +6108,7 @@
u64 objectHandle
const char* pObjectName
}
-
+
@extension("VK_EXT_debug_utils") // 129
class VkDebugUtilsObjectTagInfoEXT {
VkStructureType sType
@@ -6002,7 +6119,7 @@
platform.size_t tagSize
const void* pTag
}
-
+
@extension("VK_EXT_debug_utils") // 129
class VkDebugUtilsLabelEXT {
VkStructureType sType
@@ -6341,6 +6458,84 @@
VkValidationCacheEXT validationCache
}
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkDescriptorSetLayoutBindingFlagsCreateInfoEXT {
+ VkStructureType sType
+ const void* pNext
+ u32 bindingCount
+ const VkDescriptorBindingFlagsEXT* pBindingFlags
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkPhysicalDeviceDescriptorIndexingFeaturesEXT {
+ VkStructureType sType
+ void* pNext
+ VkBool32 shaderInputAttachmentArrayDynamicIndexing
+ VkBool32 shaderUniformTexelBufferArrayDynamicIndexing
+ VkBool32 shaderStorageTexelBufferArrayDynamicIndexing
+ VkBool32 shaderUniformBufferArrayNonUniformIndexing
+ VkBool32 shaderSampledImageArrayNonUniformIndexing
+ VkBool32 shaderStorageBufferArrayNonUniformIndexing
+ VkBool32 shaderStorageImageArrayNonUniformIndexing
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexing
+ VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing
+ VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing
+ VkBool32 descriptorBindingUniformBufferUpdateAfterBind
+ VkBool32 descriptorBindingSampledImageUpdateAfterBind
+ VkBool32 descriptorBindingStorageImageUpdateAfterBind
+ VkBool32 descriptorBindingStorageBufferUpdateAfterBind
+ VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind
+ VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind
+ VkBool32 descriptorBindingUpdateUnusedWhilePending
+ VkBool32 descriptorBindingPartiallyBound
+ VkBool32 descriptorBindingVariableDescriptorCount
+ VkBool32 runtimeDescriptorArray
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkPhysicalDeviceDescriptorIndexingPropertiesEXT {
+ VkStructureType sType
+ void* pNext
+ u32 maxUpdateAfterBindDescriptorsInAllPools
+ VkBool32 shaderUniformBufferArrayNonUniformIndexingNative
+ VkBool32 shaderSampledImageArrayNonUniformIndexingNative
+ VkBool32 shaderStorageBufferArrayNonUniformIndexingNative
+ VkBool32 shaderStorageImageArrayNonUniformIndexingNative
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative
+ VkBool32 robustBufferAccessUpdateAfterBind
+ VkBool32 quadDivergentImplicitLod
+ u32 maxPerStageDescriptorUpdateAfterBindSamplers
+ u32 maxPerStageDescriptorUpdateAfterBindUniformBuffers
+ u32 maxPerStageDescriptorUpdateAfterBindStorageBuffers
+ u32 maxPerStageDescriptorUpdateAfterBindSampledImages
+ u32 maxPerStageDescriptorUpdateAfterBindStorageImages
+ u32 maxPerStageDescriptorUpdateAfterBindInputAttachments
+ u32 maxPerStageUpdateAfterBindResources
+ u32 maxDescriptorSetUpdateAfterBindSamplers
+ u32 maxDescriptorSetUpdateAfterBindUniformBuffers
+ u32 maxDescriptorSetUpdateAfterBindUniformBuffersDynamic
+ u32 maxDescriptorSetUpdateAfterBindStorageBuffers
+ u32 maxDescriptorSetUpdateAfterBindStorageBuffersDynamic
+ u32 maxDescriptorSetUpdateAfterBindSampledImages
+ u32 maxDescriptorSetUpdateAfterBindStorageImages
+ u32 maxDescriptorSetUpdateAfterBindInputAttachments
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkDescriptorSetVariableDescriptorCountAllocateInfoEXT {
+ VkStructureType sType
+ const void* pNext
+ u32 descriptorSetCount
+ const u32* pDescriptorCounts
+}
+
+@extension("VK_EXT_descriptor_indexing") // 162
+class VkDescriptorSetVariableDescriptorCountLayoutSupportEXT {
+ VkStructureType sType
+ void* pNext
+ u32 maxVariableDescriptorCount
+}
+
@extension("VK_KHR_maintenance3") // 169
class VkPhysicalDeviceMaintenance3PropertiesKHR {
VkStructureType sType
@@ -6385,6 +6580,47 @@
VkDeviceSize minImportedHostPointerAlignment
}
+@extension("VK_AMD_shader_core_properties") // 186
+class VkPhysicalDeviceShaderCorePropertiesAMD {
+ VkStructureType sType
+ void* pNext
+ u32 shaderEngineCount
+ u32 shaderArraysPerEngineCount
+ u32 computeUnitsPerShaderArray
+ u32 simdPerComputeUnit
+ u32 wavefrontsPerSimd
+ u32 wavefrontSize
+ u32 sgprsPerSimd
+ u32 minSgprAllocation
+ u32 maxSgprAllocation
+ u32 sgprAllocationGranularity
+ u32 vgprsPerSimd
+ u32 minVgprAllocation
+ u32 maxVgprAllocation
+ u32 vgprAllocationGranularity
+}
+
+@extension("VK_EXT_vertex_attribute_divisor") // 191
+class VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT {
+ VkStructureType sType
+ void* pNext
+ u32 maxVertexAttribDivisor
+}
+
+@extension("VK_EXT_vertex_attribute_divisor") // 191
+class VkVertexInputBindingDivisorDescriptionEXT {
+ u32 binding
+ u32 divisor
+}
+
+@extension("VK_EXT_vertex_attribute_divisor") // 191
+class VkPipelineVertexInputDivisorStateCreateInfoEXT {
+ VkStructureType sType
+ const void* pNext
+ u32 vertexBindingDivisorCount
+ const VkVertexInputBindingDivisorDescriptionEXT* pVertexBindingDivisors
+}
+
////////////////
// Commands //
@@ -9843,6 +10079,39 @@
return ?
}
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetPhysicalDeviceDisplayProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ u32* pPropertyCount,
+ VkDisplayProperties2KHR* pProperties) {
+ return ?
+}
+
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ u32* pPropertyCount,
+ VkDisplayPlaneProperties2KHR* pProperties) {
+ return ?
+}
+
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetDisplayModeProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ u32* pPropertyCount,
+ VkDisplayModeProperties2KHR* pProperties) {
+ return ?
+}
+
+@extension("VK_KHR_display_properties2") // 122
+cmd VkResult vkGetDisplayPlaneCapabilities2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo,
+ VkDisplayPlaneCapabilities2KHR* pCapabilities) {
+ return ?
+}
+
@extension("VK_MVK_ios_surface") // 123
cmd VkResult vkCreateIOSSurfaceMVK(
VkInstance instance,
@@ -9878,36 +10147,36 @@
const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
return ?
}
-
+
@extension("VK_EXT_debug_utils") // 129
cmd VkResult vkSetDebugUtilsObjectTagEXT(
VkDevice device,
const VkDebugUtilsObjectTagInfoEXT* pTagInfo) {
return ?
}
-
+
@extension("VK_EXT_debug_utils") // 129
cmd void vkQueueBeginDebugUtilsLabelEXT(
VkQueue queue,
const VkDebugUtilsLabelEXT* pLabelInfo) {
}
-
+
@extension("VK_EXT_debug_utils") // 129
cmd void vkQueueEndDebugUtilsLabelEXT(VkQueue queue) {
}
-
+
@extension("VK_EXT_debug_utils") // 129
cmd void vkQueueInsertDebugUtilsLabelEXT(
VkQueue queue,
const VkDebugUtilsLabelEXT* pLabelInfo) {
}
-
+
@extension("VK_EXT_debug_utils") // 129
cmd void vkCmdBeginDebugUtilsLabelEXT(
VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT* pLabelInfo) {
}
-
+
@extension("VK_EXT_debug_utils") // 129
cmd void vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
}
@@ -10068,6 +10337,28 @@
VkDescriptorSetLayoutSupportKHR* pSupport) {
}
+@extension("VK_KHR_draw_indirect_count") // 170
+cmd void vkCmdDrawIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ u32 maxDrawCount,
+ u32 stride) {
+}
+
+@extension("VK_KHR_draw_indirect_count") // 170
+cmd void vkCmdDrawIndexedIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ u32 maxDrawCount,
+ u32 stride) {
+}
+
@extension("VK_EXT_external_memory_host") // 179
cmd VkResult vkGetMemoryHostPointerPropertiesEXT(
VkDevice device,
@@ -10077,6 +10368,15 @@
return ?
}
+@extension("VK_AMD_buffer_marker") // 180
+cmd void vkCmdWriteBufferMarkerAMD(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ u32 marker) {
+}
+
////////////////
// Validation //
////////////////
diff --git a/vulkan/doc/README b/vulkan/doc/README
new file mode 100644
index 0000000..d1dc2e1
--- /dev/null
+++ b/vulkan/doc/README
@@ -0,0 +1,2 @@
+The former contents of implementors_guide/ are now at
+https://source.android.com/devices/graphics/implement-vulkan
diff --git a/vulkan/doc/implementors_guide/implementors_guide-docinfo.adoc b/vulkan/doc/implementors_guide/implementors_guide-docinfo.adoc
deleted file mode 100644
index 69b8c61..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide-docinfo.adoc
+++ /dev/null
@@ -1,23 +0,0 @@
-<style type="text/css">
-
-code,div.listingblock {
- max-width: 68em;
-}
-
-p {
- max-width: 50em;
-}
-
-table {
- max-width: 50em;
-}
-
-table.tableblock {
- border-width: 1px;
-}
-
-h2 {
- max-width: 35em;
-}
-
-</style>
diff --git a/vulkan/doc/implementors_guide/implementors_guide.adoc b/vulkan/doc/implementors_guide/implementors_guide.adoc
deleted file mode 100644
index 24af950..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide.adoc
+++ /dev/null
@@ -1,209 +0,0 @@
-// asciidoc -b html5 -d book -f implementors_guide.conf implementors_guide.adoc
-= Vulkan on Android Implementor's Guide =
-:toc: right
-:numbered:
-:revnumber: 5
-
-This document is intended for GPU IHVs writing Vulkan drivers for Android, and OEMs integrating them for specific devices. It describes how a Vulkan driver interacts with the system, how GPU-specific tools should be installed, and Android-specific requirements.
-
-== Architecture ==
-
-The primary interface between Vulkan applications and a device's Vulkan driver is the loader, which is part of AOSP and installed at +/system/lib[64]/libvulkan.so+. The loader provides the core Vulkan API entry points, as well as entry points of a few extensions that are required on Android and always present. In particular, the window system integration (WSI) extensions are exported by the loader and primarily implemented in it rather than the driver. The loader also supports enumerating and loading layers which can expose additional extensions and/or intercept core API calls on their way to the driver.
-
-The NDK will include a stub +libvulkan.so+ exporting the same symbols as the loader. Calling the Vulkan functions exported from +libvulkan.so+ will enter trampoline functions in the loader which will dispatch to the appropriate layer or driver based on their first argument. The +vkGet*ProcAddr+ calls will return the function pointers that the trampolines would dispatch to, so calling through these function pointers rather than the exported symbols will be slightly more efficient since it skips the trampoline and dispatch.
-
-=== Driver Enumeration and Loading ===
-
-Android expects the GPUs available to the system to be known when the system image is built, so its driver enumeration process isn't as elaborate as on other platforms. The loader will use the existing HAL mechanism for discovering and loading the driver. As of this writing, the preferred paths for 32-bit and 64-bit Vulkan drivers are:
-
- /vendor/lib/hw/vulkan.<ro.product.platform>.so
- /vendor/lib64/hw/vulkan.<ro.product.platform>.so
-
-where +<ro.product.platform>+ is replaced by the value of the system property of that name. See https://android.googlesource.com/platform/hardware/libhardware/+/master/hardware.c[libhardware/hardware.c] for details and supported alternative locations.
-
-The Vulkan +hw_module_t+ derivative is currently trivial. If support for multiple drivers is ever added, the HAL module will export a list of strings that can be passed to the module +open+ call. For the time being, only one driver is supported, and the constant string +HWVULKAN_DEVICE_0+ is passed to +open+.
-
-The Vulkan +hw_device_t+ derivative corresponds to a single driver, though that driver can support multiple Vulkan physical devices. The +hw_device_t+ structure contains a function pointer for the +vkGetInstanceProcAddr+ function. The loader finds all other driver Vulkan functions by calling that +vkGetInstanceProcAddr+ function.
-
-=== Layer Discovery and Loading ===
-
-Android's security model and policies differ significantly from other platforms. In particular, Android does not allow loading external code into a non-debuggable process on production (non-rooted) devices, nor does it allow external code to inspect or control the process's memory/state/etc. This includes a prohibition on saving core dumps, API traces, etc. to disk for later inspection. So only layers delivered as part of the application will be enabled on production devices, and drivers must also not provide functionality that violates these policies.
-
-There are three major use cases for layers:
-
-1. Development-time layers: validation layers, shims for tracing/profiling/debugging tools, etc. These shouldn't be installed on the system image of production devices: they would be a waste of space for most users, and they should be updateable without requiring a system update. A developer wishing to use one of these during development has the ability to modify their application package (e.g. adding a file to their native libraries directory). IHV and OEM engineers who are trying to diagnose failures in shipping, unmodifiable apps are assumed to have access to non-production (rooted) builds of the system image.
-
-2. Utility layers, such as a layer that implements a heap for device memory. These layers will almost always expose extensions. Developers choose which layers, and which versions of those layers, to use in their application; different applications that use the same layer may still use different versions. Developers will choose which of these layers to ship in their application package.
-
-3. Injected layers, like framerate, social network, or game launcher overlays, which are provided by the user or some other application without the application's knowledge or consent. These violate Android's security policies and will not be supported.
-
-In the normal state the loader will only search in the application's normal library search path (as defined by the system ClassLoader) for layers. It will attempt to load any shared library named +libVkLayer_*.so+ as a layer library. Android does not use manifests to describe layers: because layers must have been deliberately included in the application by the developer, the motivation for manifests on other platforms don't apply.
-
-On debuggable devices (+ro.debuggable+ property exists and is non-zero, generally rooted or engineering builds) the loader will also search the directory +/data/local/debug/vulkan+ and attempt to load layer libraries it finds there. This directory doesn't exist by default. On Android N and later, because this location is writable by adb, SELinux policies prevent mapping code located here as executable. So to use layers from here, SELinux enforcement must be disabled: +adb shell setenforce 0+. This mechanism is not intended for application developers, only for IHV and OEM engineers working on test devices that don't have private or sensitive data.
-
-Our goal is to allow layers to be ported with only build-environment changes between Android and other platforms. For this to work, layers must properly implement things like +vkGetInstanceLayerProperties+ and +vkGetInstanceExtensionProperties+, even though the LunarG loader doesn't use them (it gets the information from manifests instead).
-
-== Window System Integration ==
-
-The +vk_wsi_swapchin+ and +vk_wsi_device_swapchain+ extensions are primarily be implemented by the platform and live in +libvulkan.so+. The +VkSwapchain+ object and all interaction with +ANativeWindow+ will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver's +vkGetDeviceProcAddr+ functions, after passing through any enabled layers.
-
-Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The swapchain usage bits are defined as
-[source,c]
-----
-typedef enum VkSwapchainImageUsageFlagBitsANDROID {
- VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID = 0x00000001,
- VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
-} VkSwapchainImageUsageFlagBitsANDROID;
-typedef VkFlags VkSwapchainImageUsageFlagsANDROID;
-----
-
-Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
-[source,c]
-----
-VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
- VkDevice device,
- VkFormat format,
- VkImageUsageFlags imageUsage,
- VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
- uint64_t* grallocConsumerUsage,
- uint64_t* grallocProducerUsage,
-);
-----
-The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocConsumerUsage+ and +*grallocProducerUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
-
-An older version of this function is deprecated but still supported for backwards compatibility; it will be used if +vkGetSwapchainGrallocUsage2ANDROID+ is not supported:
-[source,c]
-----
-VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
- VkDevice device,
- VkFormat format,
- VkImageUsageFlags imageUsage,
- int* grallocUsage
-);
-----
-
-+VkNativeBufferANDROID+ is a +vkCreateImage+ extension structure for creating an image backed by a gralloc buffer. This structure is provided to +vkCreateImage+ in the +VkImageCreateInfo+ structure chain. Calls to +vkCreateImage+ with this structure will happen during the first call to +vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)+. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a +VkImage+ for each one.
-
-[source,c]
-----
-typedef struct {
- VkStructureType sType; // must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID
- const void* pNext;
-
- // Buffer handle and stride returned from gralloc alloc()
- buffer_handle_t handle;
- int stride;
-
- // Gralloc format and usage requested when the buffer was allocated.
- int format;
- int usage; // deprecated
- struct {
- uint64_t consumer;
- uint64_t producer;
- } usage2;
-} VkNativeBufferANDROID;
-----
-
-When creating a gralloc-backed image, the +VkImageCreateInfo+ will have:
-[source,txt]
-----
- .imageType = VK_IMAGE_TYPE_2D
- .format = a VkFormat matching the format requested for the gralloc buffer
- .extent = the 2D dimensions requested for the gralloc buffer
- .mipLevels = 1
- .arraySize = 1
- .samples = 1
- .tiling = VK_IMAGE_TILING_OPTIMAL
- .usage = VkSwapChainCreateInfoWSI::imageUsageFlags
- .flags = 0
- .sharingMode = VkSwapChainCreateInfoWSI::sharingMode
- .queueFamilyCount = VkSwapChainCreateInfoWSI::queueFamilyCount
- .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices
-----
-
-Additionally, when any swapchain image usage flags are required for the swapchain, the platform will provide a +VkSwapchainImageCreateInfoANDROID+ extension structure in the +VkImageCreateInfo+ chain provided to +vkCreateImage+, containing the swapchain image usage flags:
-[source,c]
-----
-typedef struct {
- VkStructureType sType; // must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID
- const void* pNext;
-
- VkSwapchainImageUsageFlagsANDROID usage;
-} VkSwapchainImageCreateInfoANDROID;
-----
-
-+vkAcquireImageANDROID+ acquires ownership of a swapchain image and imports an
-externally-signalled native fence into both an existing VkSemaphore object
-and an existing VkFence object:
-
-[source,c]
-----
-VkResult VKAPI vkAcquireImageANDROID(
- VkDevice device,
- VkImage image,
- int nativeFenceFd,
- VkSemaphore semaphore,
- VkFence fence
-);
-----
-
-This function is called during +vkAcquireNextImageWSI+ to import a native
-fence into the +VkSemaphore+ and +VkFence+ objects provided by the
-application. Both semaphore and fence objects are optional in this call. The
-driver may also use this opportunity to recognize and handle any external
-changes to the gralloc buffer state; many drivers won't need to do anything
-here. This call puts the +VkSemaphore+ and +VkFence+ into the same "pending"
-state as +vkQueueSignalSemaphore+ and +vkQueueSubmit+ respectively, so queues
-can wait on the semaphore and the application can wait on the fence. Both
-objects become signalled when the underlying native fence signals; if the
-native fence has already signalled, then the semaphore will be in the signalled
-state when this function returns. The driver takes ownership of the fence fd
-and is responsible for closing it when no longer needed. It must do so even if
-neither a semaphore or fence object is provided, or even if
-+vkAcquireImageANDROID+ fails and returns an error. If +fenceFd+ is -1, it
-is as if the native fence was already signalled.
-
-+vkQueueSignalReleaseImageANDROID+ prepares a swapchain image for external use, and creates a native fence and schedules it to be signalled when prior work on the queue has completed.
-
-[source,c]
-----
-VkResult VKAPI vkQueueSignalReleaseImageANDROID(
- VkQueue queue,
- uint32_t waitSemaphoreCount,
- const VkSemaphore* pWaitSemaphores,
- VkImage image,
- int* pNativeFenceFd
-);
-----
-
-This will be called during +vkQueuePresentWSI+ on the provided queue. Effects are similar to +vkQueueSignalSemaphore+, except with a native fence instead of a semaphore. The native fence must: not signal until the +waitSemaphoreCount+ semaphores in +pWaitSemaphores+ have signaled. Unlike +vkQueueSignalSemaphore+, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set +*pNativeFenceFd+ to -1. The file descriptor returned in +*pNativeFenceFd+ is owned and will be closed by the caller. Many drivers will be able to ignore the +image+ parameter, but some may need to prepare CPU-side data structures associated with a gralloc buffer for use by external image consumers. Preparing buffer contents for use by external consumers should have been done asynchronously as part of transitioning the image to +VK_IMAGE_LAYOUT_PRESENT_SRC_KHR+.
-
-If +image+ was created with +VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID+, then the driver must tolerate +vkQueueSignalReleaseImageANDROID+ being called repeatedly without intervening calls to +vkAcquireImageANDROID+.
-
-== History ==
-
-. *2015-07-08* Initial version
-. *2015-08-16*
- * Renamed to Implementor's Guide
- * Wording and formatting changes
- * Updated based on resolution of Khronos bug 14265
- * Deferred support for multiple drivers
-. *2015-11-04*
- * Added vkGetSwapchainGrallocUsageANDROID
- * Replaced vkImportNativeFenceANDROID and vkQueueSignalNativeFenceANDROID
- with vkAcquireImageANDROID and vkQueueSignalReleaseImageANDROID, to allow
- drivers to known the ownership state of swapchain images.
-. *2015-12-03*
- * Added a VkFence parameter to vkAcquireImageANDROID corresponding to the
- parameter added to vkAcquireNextImageKHR.
-. *2016-01-08*
- * Added waitSemaphoreCount and pWaitSemaphores parameters to vkQueueSignalReleaseImageANDROID.
-. *2016-06-17*
- * Updates to reflect final behavior, closed some TBDs now that they've BDed.
-. *2017-01-06*
- * Extension version 6
- * Added VkSwapchainImageUsageFlagBitsANDROID
- * Added vkGetSwapchainGrallocUsage2ANDROID
- * Added VkSwapchainImageCreateInfoANDROID
-. *2017-02-09*
- * Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
\ No newline at end of file
diff --git a/vulkan/doc/implementors_guide/implementors_guide.conf b/vulkan/doc/implementors_guide/implementors_guide.conf
deleted file mode 100644
index 572a4d9..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-[attributes]
-newline=\n
-
-[replacements]
-\+\/-=±
diff --git a/vulkan/doc/implementors_guide/implementors_guide.html b/vulkan/doc/implementors_guide/implementors_guide.html
deleted file mode 100644
index 9fecce5..0000000
--- a/vulkan/doc/implementors_guide/implementors_guide.html
+++ /dev/null
@@ -1,1076 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta name="generator" content="AsciiDoc 8.6.9">
-<title>Vulkan on Android Implementor’s Guide</title>
-<style type="text/css">
-/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
-
-/* Default font. */
-body {
- font-family: Georgia,serif;
-}
-
-/* Title font. */
-h1, h2, h3, h4, h5, h6,
-div.title, caption.title,
-thead, p.table.header,
-#toctitle,
-#author, #revnumber, #revdate, #revremark,
-#footer {
- font-family: Arial,Helvetica,sans-serif;
-}
-
-body {
- margin: 1em 5% 1em 5%;
-}
-
-a {
- color: blue;
- text-decoration: underline;
-}
-a:visited {
- color: fuchsia;
-}
-
-em {
- font-style: italic;
- color: navy;
-}
-
-strong {
- font-weight: bold;
- color: #083194;
-}
-
-h1, h2, h3, h4, h5, h6 {
- color: #527bbd;
- margin-top: 1.2em;
- margin-bottom: 0.5em;
- line-height: 1.3;
-}
-
-h1, h2, h3 {
- border-bottom: 2px solid silver;
-}
-h2 {
- padding-top: 0.5em;
-}
-h3 {
- float: left;
-}
-h3 + * {
- clear: left;
-}
-h5 {
- font-size: 1.0em;
-}
-
-div.sectionbody {
- margin-left: 0;
-}
-
-hr {
- border: 1px solid silver;
-}
-
-p {
- margin-top: 0.5em;
- margin-bottom: 0.5em;
-}
-
-ul, ol, li > p {
- margin-top: 0;
-}
-ul > li { color: #aaa; }
-ul > li > * { color: black; }
-
-.monospaced, code, pre {
- font-family: "Courier New", Courier, monospace;
- font-size: inherit;
- color: navy;
- padding: 0;
- margin: 0;
-}
-pre {
- white-space: pre-wrap;
-}
-
-#author {
- color: #527bbd;
- font-weight: bold;
- font-size: 1.1em;
-}
-#email {
-}
-#revnumber, #revdate, #revremark {
-}
-
-#footer {
- font-size: small;
- border-top: 2px solid silver;
- padding-top: 0.5em;
- margin-top: 4.0em;
-}
-#footer-text {
- float: left;
- padding-bottom: 0.5em;
-}
-#footer-badges {
- float: right;
- padding-bottom: 0.5em;
-}
-
-#preamble {
- margin-top: 1.5em;
- margin-bottom: 1.5em;
-}
-div.imageblock, div.exampleblock, div.verseblock,
-div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
-div.admonitionblock {
- margin-top: 1.0em;
- margin-bottom: 1.5em;
-}
-div.admonitionblock {
- margin-top: 2.0em;
- margin-bottom: 2.0em;
- margin-right: 10%;
- color: #606060;
-}
-
-div.content { /* Block element content. */
- padding: 0;
-}
-
-/* Block element titles. */
-div.title, caption.title {
- color: #527bbd;
- font-weight: bold;
- text-align: left;
- margin-top: 1.0em;
- margin-bottom: 0.5em;
-}
-div.title + * {
- margin-top: 0;
-}
-
-td div.title:first-child {
- margin-top: 0.0em;
-}
-div.content div.title:first-child {
- margin-top: 0.0em;
-}
-div.content + div.title {
- margin-top: 0.0em;
-}
-
-div.sidebarblock > div.content {
- background: #ffffee;
- border: 1px solid #dddddd;
- border-left: 4px solid #f0f0f0;
- padding: 0.5em;
-}
-
-div.listingblock > div.content {
- border: 1px solid #dddddd;
- border-left: 5px solid #f0f0f0;
- background: #f8f8f8;
- padding: 0.5em;
-}
-
-div.quoteblock, div.verseblock {
- padding-left: 1.0em;
- margin-left: 1.0em;
- margin-right: 10%;
- border-left: 5px solid #f0f0f0;
- color: #888;
-}
-
-div.quoteblock > div.attribution {
- padding-top: 0.5em;
- text-align: right;
-}
-
-div.verseblock > pre.content {
- font-family: inherit;
- font-size: inherit;
-}
-div.verseblock > div.attribution {
- padding-top: 0.75em;
- text-align: left;
-}
-/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
-div.verseblock + div.attribution {
- text-align: left;
-}
-
-div.admonitionblock .icon {
- vertical-align: top;
- font-size: 1.1em;
- font-weight: bold;
- text-decoration: underline;
- color: #527bbd;
- padding-right: 0.5em;
-}
-div.admonitionblock td.content {
- padding-left: 0.5em;
- border-left: 3px solid #dddddd;
-}
-
-div.exampleblock > div.content {
- border-left: 3px solid #dddddd;
- padding-left: 0.5em;
-}
-
-div.imageblock div.content { padding-left: 0; }
-span.image img { border-style: none; vertical-align: text-bottom; }
-a.image:visited { color: white; }
-
-dl {
- margin-top: 0.8em;
- margin-bottom: 0.8em;
-}
-dt {
- margin-top: 0.5em;
- margin-bottom: 0;
- font-style: normal;
- color: navy;
-}
-dd > *:first-child {
- margin-top: 0.1em;
-}
-
-ul, ol {
- list-style-position: outside;
-}
-ol.arabic {
- list-style-type: decimal;
-}
-ol.loweralpha {
- list-style-type: lower-alpha;
-}
-ol.upperalpha {
- list-style-type: upper-alpha;
-}
-ol.lowerroman {
- list-style-type: lower-roman;
-}
-ol.upperroman {
- list-style-type: upper-roman;
-}
-
-div.compact ul, div.compact ol,
-div.compact p, div.compact p,
-div.compact div, div.compact div {
- margin-top: 0.1em;
- margin-bottom: 0.1em;
-}
-
-tfoot {
- font-weight: bold;
-}
-td > div.verse {
- white-space: pre;
-}
-
-div.hdlist {
- margin-top: 0.8em;
- margin-bottom: 0.8em;
-}
-div.hdlist tr {
- padding-bottom: 15px;
-}
-dt.hdlist1.strong, td.hdlist1.strong {
- font-weight: bold;
-}
-td.hdlist1 {
- vertical-align: top;
- font-style: normal;
- padding-right: 0.8em;
- color: navy;
-}
-td.hdlist2 {
- vertical-align: top;
-}
-div.hdlist.compact tr {
- margin: 0;
- padding-bottom: 0;
-}
-
-.comment {
- background: yellow;
-}
-
-.footnote, .footnoteref {
- font-size: 0.8em;
-}
-
-span.footnote, span.footnoteref {
- vertical-align: super;
-}
-
-#footnotes {
- margin: 20px 0 20px 0;
- padding: 7px 0 0 0;
-}
-
-#footnotes div.footnote {
- margin: 0 0 5px 0;
-}
-
-#footnotes hr {
- border: none;
- border-top: 1px solid silver;
- height: 1px;
- text-align: left;
- margin-left: 0;
- width: 20%;
- min-width: 100px;
-}
-
-div.colist td {
- padding-right: 0.5em;
- padding-bottom: 0.3em;
- vertical-align: top;
-}
-div.colist td img {
- margin-top: 0.3em;
-}
-
-@media print {
- #footer-badges { display: none; }
-}
-
-#toc {
- margin-bottom: 2.5em;
-}
-
-#toctitle {
- color: #527bbd;
- font-size: 1.1em;
- font-weight: bold;
- margin-top: 1.0em;
- margin-bottom: 0.1em;
-}
-
-div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
- margin-top: 0;
- margin-bottom: 0;
-}
-div.toclevel2 {
- margin-left: 2em;
- font-size: 0.9em;
-}
-div.toclevel3 {
- margin-left: 4em;
- font-size: 0.9em;
-}
-div.toclevel4 {
- margin-left: 6em;
- font-size: 0.9em;
-}
-
-span.aqua { color: aqua; }
-span.black { color: black; }
-span.blue { color: blue; }
-span.fuchsia { color: fuchsia; }
-span.gray { color: gray; }
-span.green { color: green; }
-span.lime { color: lime; }
-span.maroon { color: maroon; }
-span.navy { color: navy; }
-span.olive { color: olive; }
-span.purple { color: purple; }
-span.red { color: red; }
-span.silver { color: silver; }
-span.teal { color: teal; }
-span.white { color: white; }
-span.yellow { color: yellow; }
-
-span.aqua-background { background: aqua; }
-span.black-background { background: black; }
-span.blue-background { background: blue; }
-span.fuchsia-background { background: fuchsia; }
-span.gray-background { background: gray; }
-span.green-background { background: green; }
-span.lime-background { background: lime; }
-span.maroon-background { background: maroon; }
-span.navy-background { background: navy; }
-span.olive-background { background: olive; }
-span.purple-background { background: purple; }
-span.red-background { background: red; }
-span.silver-background { background: silver; }
-span.teal-background { background: teal; }
-span.white-background { background: white; }
-span.yellow-background { background: yellow; }
-
-span.big { font-size: 2em; }
-span.small { font-size: 0.6em; }
-
-span.underline { text-decoration: underline; }
-span.overline { text-decoration: overline; }
-span.line-through { text-decoration: line-through; }
-
-div.unbreakable { page-break-inside: avoid; }
-
-
-/*
- * xhtml11 specific
- *
- * */
-
-div.tableblock {
- margin-top: 1.0em;
- margin-bottom: 1.5em;
-}
-div.tableblock > table {
- border: 3px solid #527bbd;
-}
-thead, p.table.header {
- font-weight: bold;
- color: #527bbd;
-}
-p.table {
- margin-top: 0;
-}
-/* Because the table frame attribute is overriden by CSS in most browsers. */
-div.tableblock > table[frame="void"] {
- border-style: none;
-}
-div.tableblock > table[frame="hsides"] {
- border-left-style: none;
- border-right-style: none;
-}
-div.tableblock > table[frame="vsides"] {
- border-top-style: none;
- border-bottom-style: none;
-}
-
-
-/*
- * html5 specific
- *
- * */
-
-table.tableblock {
- margin-top: 1.0em;
- margin-bottom: 1.5em;
-}
-thead, p.tableblock.header {
- font-weight: bold;
- color: #527bbd;
-}
-p.tableblock {
- margin-top: 0;
-}
-table.tableblock {
- border-width: 3px;
- border-spacing: 0px;
- border-style: solid;
- border-color: #527bbd;
- border-collapse: collapse;
-}
-th.tableblock, td.tableblock {
- border-width: 1px;
- padding: 4px;
- border-style: solid;
- border-color: #527bbd;
-}
-
-table.tableblock.frame-topbot {
- border-left-style: hidden;
- border-right-style: hidden;
-}
-table.tableblock.frame-sides {
- border-top-style: hidden;
- border-bottom-style: hidden;
-}
-table.tableblock.frame-none {
- border-style: hidden;
-}
-
-th.tableblock.halign-left, td.tableblock.halign-left {
- text-align: left;
-}
-th.tableblock.halign-center, td.tableblock.halign-center {
- text-align: center;
-}
-th.tableblock.halign-right, td.tableblock.halign-right {
- text-align: right;
-}
-
-th.tableblock.valign-top, td.tableblock.valign-top {
- vertical-align: top;
-}
-th.tableblock.valign-middle, td.tableblock.valign-middle {
- vertical-align: middle;
-}
-th.tableblock.valign-bottom, td.tableblock.valign-bottom {
- vertical-align: bottom;
-}
-
-
-/*
- * manpage specific
- *
- * */
-
-body.manpage h1 {
- padding-top: 0.5em;
- padding-bottom: 0.5em;
- border-top: 2px solid silver;
- border-bottom: 2px solid silver;
-}
-body.manpage h2 {
- border-style: none;
-}
-body.manpage div.sectionbody {
- margin-left: 3em;
-}
-
-@media print {
- body.manpage div#toc { display: none; }
-}
-
-
-</style>
-<script type="text/javascript">
-/*<+'])');
- // Function that scans the DOM tree for header elements (the DOM2
- // nodeIterator API would be a better technique but not supported by all
- // browsers).
- var iterate = function (el) {
- for (var i = el.firstChild; i != null; i = i.nextSibling) {
- if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
- var mo = re.exec(i.tagName);
- if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
- result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
- }
- iterate(i);
- }
- }
- }
- iterate(el);
- return result;
- }
-
- var toc = document.getElementById("toc");
- if (!toc) {
- return;
- }
-
- // Delete existing TOC entries in case we're reloading the TOC.
- var tocEntriesToRemove = [];
- var i;
- for (i = 0; i < toc.childNodes.length; i++) {
- var entry = toc.childNodes[i];
- if (entry.nodeName.toLowerCase() == 'div'
- && entry.getAttribute("class")
- && entry.getAttribute("class").match(/^toclevel/))
- tocEntriesToRemove.push(entry);
- }
- for (i = 0; i < tocEntriesToRemove.length; i++) {
- toc.removeChild(tocEntriesToRemove[i]);
- }
-
- // Rebuild TOC entries.
- var entries = tocEntries(document.getElementById("content"), toclevels);
- for (var i = 0; i < entries.length; ++i) {
- var entry = entries[i];
- if (entry.element.id == "")
- entry.element.id = "_toc_" + i;
- var a = document.createElement("a");
- a.href = "#" + entry.element.id;
- a.appendChild(document.createTextNode(entry.text));
- var div = document.createElement("div");
- div.appendChild(a);
- div.className = "toclevel" + entry.toclevel;
- toc.appendChild(div);
- }
- if (entries.length == 0)
- toc.parentNode.removeChild(toc);
-},
-
-
-/////////////////////////////////////////////////////////////////////
-// Footnotes generator
-/////////////////////////////////////////////////////////////////////
-
-/* Based on footnote generation code from:
- * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
- */
-
-footnotes: function () {
- // Delete existing footnote entries in case we're reloading the footnodes.
- var i;
- var noteholder = document.getElementById("footnotes");
- if (!noteholder) {
- return;
- }
- var entriesToRemove = [];
- for (i = 0; i < noteholder.childNodes.length; i++) {
- var entry = noteholder.childNodes[i];
- if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
- entriesToRemove.push(entry);
- }
- for (i = 0; i < entriesToRemove.length; i++) {
- noteholder.removeChild(entriesToRemove[i]);
- }
-
- // Rebuild footnote entries.
- var cont = document.getElementById("content");
- var spans = cont.getElementsByTagName("span");
- var refs = {};
- var n = 0;
- for (i=0; i<spans.length; i++) {
- if (spans[i].className == "footnote") {
- n++;
- var note = spans[i].getAttribute("data-note");
- if (!note) {
- // Use [\s\S] in place of . so multi-line matches work.
- // Because JavaScript has no s (dotall) regex flag.
- note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
- spans[i].innerHTML =
- "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
- "' title='View footnote' class='footnote'>" + n + "</a>]";
- spans[i].setAttribute("data-note", note);
- }
- noteholder.innerHTML +=
- "<div class='footnote' id='_footnote_" + n + "'>" +
- "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
- n + "</a>. " + note + "</div>";
- var id =spans[i].getAttribute("id");
- if (id != null) refs["#"+id] = n;
- }
- }
- if (n == 0)
- noteholder.parentNode.removeChild(noteholder);
- else {
- // Process footnoterefs.
- for (i=0; i<spans.length; i++) {
- if (spans[i].className == "footnoteref") {
- var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
- href = href.match(/#.*/)[0]; // Because IE return full URL.
- n = refs[href];
- spans[i].innerHTML =
- "[<a href='#_footnote_" + n +
- "' title='View footnote' class='footnote'>" + n + "</a>]";
- }
- }
- }
-},
-
-install: function(toclevels) {
- var timerId;
-
- function reinstall() {
- asciidoc.footnotes();
- if (toclevels) {
- asciidoc.toc(toclevels);
- }
- }
-
- function reinstallAndRemoveTimer() {
- clearInterval(timerId);
- reinstall();
- }
-
- timerId = setInterval(reinstall, 500);
- if (document.addEventListener)
- document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
- else
- window.onload = reinstallAndRemoveTimer;
-}
-
-}
-asciidoc.install(2);
-/*]]>*/
-</script>
-</head>
-<body class="book">
-<div id="header">
-<h1>Vulkan on Android Implementor’s Guide</h1>
-<span id="revnumber">version 5</span>
-<div id="toc">
- <div id="toctitle">Table of Contents</div>
- <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
-</div>
-</div>
-<div id="content">
-<div id="preamble">
-<div class="sectionbody">
-<div class="paragraph"><p>This document is intended for GPU IHVs writing Vulkan drivers for Android, and OEMs integrating them for specific devices. It describes how a Vulkan driver interacts with the system, how GPU-specific tools should be installed, and Android-specific requirements.</p></div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_architecture">1. Architecture</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>The primary interface between Vulkan applications and a device’s Vulkan driver is the loader, which is part of AOSP and installed at <span class="monospaced">/system/lib[64]/libvulkan.so</span>. The loader provides the core Vulkan API entry points, as well as entry points of a few extensions that are required on Android and always present. In particular, the window system integration (WSI) extensions are exported by the loader and primarily implemented in it rather than the driver. The loader also supports enumerating and loading layers which can expose additional extensions and/or intercept core API calls on their way to the driver.</p></div>
-<div class="paragraph"><p>The NDK will include a stub <span class="monospaced">libvulkan.so</span> exporting the same symbols as the loader. Calling the Vulkan functions exported from <span class="monospaced">libvulkan.so</span> will enter trampoline functions in the loader which will dispatch to the appropriate layer or driver based on their first argument. The <span class="monospaced">vkGet*ProcAddr</span> calls will return the function pointers that the trampolines would dispatch to, so calling through these function pointers rather than the exported symbols will be slightly more efficient since it skips the trampoline and dispatch.</p></div>
-<div class="sect2">
-<h3 id="_driver_enumeration_and_loading">1.1. Driver Enumeration and Loading</h3>
-<div class="paragraph"><p>Android expects the GPUs available to the system to be known when the system image is built, so its driver enumeration process isn’t as elaborate as on other platforms. The loader will use the existing HAL mechanism for discovering and loading the driver. As of this writing, the preferred paths for 32-bit and 64-bit Vulkan drivers are:</p></div>
-<div class="literalblock">
-<div class="content monospaced">
-<pre>/vendor/lib/hw/vulkan.<ro.product.platform>.so
-/vendor/lib64/hw/vulkan.<ro.product.platform>.so</pre>
-</div></div>
-<div class="paragraph"><p>where <span class="monospaced"><ro.product.platform></span> is replaced by the value of the system property of that name. See <a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/hardware.c">libhardware/hardware.c</a> for details and supported alternative locations.</p></div>
-<div class="paragraph"><p>The Vulkan <span class="monospaced">hw_module_t</span> derivative is currently trivial. If support for multiple drivers is ever added, the HAL module will export a list of strings that can be passed to the module <span class="monospaced">open</span> call. For the time being, only one driver is supported, and the constant string <span class="monospaced">HWVULKAN_DEVICE_0</span> is passed to <span class="monospaced">open</span>.</p></div>
-<div class="paragraph"><p>The Vulkan <span class="monospaced">hw_device_t</span> derivative corresponds to a single driver, though that driver can support multiple Vulkan physical devices. The <span class="monospaced">hw_device_t</span> structure contains a function pointer for the <span class="monospaced">vkGetInstanceProcAddr</span> function. The loader finds all other driver Vulkan functions by calling that <span class="monospaced">vkGetInstanceProcAddr</span> function.</p></div>
-</div>
-<div class="sect2">
-<h3 id="_layer_discovery_and_loading">1.2. Layer Discovery and Loading</h3>
-<div class="paragraph"><p>Android’s security model and policies differ significantly from other platforms. In particular, Android does not allow loading external code into a non-debuggable process on production (non-rooted) devices, nor does it allow external code to inspect or control the process’s memory/state/etc. This includes a prohibition on saving core dumps, API traces, etc. to disk for later inspection. So only layers delivered as part of the application will be enabled on production devices, and drivers must also not provide functionality that violates these policies.</p></div>
-<div class="paragraph"><p>There are three major use cases for layers:</p></div>
-<div class="olist arabic"><ol class="arabic">
-<li>
-<p>
-Development-time layers: validation layers, shims for tracing/profiling/debugging tools, etc. These shouldn’t be installed on the system image of production devices: they would be a waste of space for most users, and they should be updateable without requiring a system update. A developer wishing to use one of these during development has the ability to modify their application package (e.g. adding a file to their native libraries directory). IHV and OEM engineers who are trying to diagnose failures in shipping, unmodifiable apps are assumed to have access to non-production (rooted) builds of the system image.
-</p>
-</li>
-<li>
-<p>
-Utility layers, such as a layer that implements a heap for device memory. These layers will almost always expose extensions. Developers choose which layers, and which versions of those layers, to use in their application; different applications that use the same layer may still use different versions. Developers will choose which of these layers to ship in their application package.
-</p>
-</li>
-<li>
-<p>
-Injected layers, like framerate, social network, or game launcher overlays, which are provided by the user or some other application without the application’s knowledge or consent. These violate Android’s security policies and will not be supported.
-</p>
-</li>
-</ol></div>
-<div class="paragraph"><p>In the normal state the loader will only search in the application’s normal library search path (as defined by the system ClassLoader) for layers. It will attempt to load any shared library named <span class="monospaced">libVkLayer_*.so</span> as a layer library. Android does not use manifests to describe layers: because layers must have been deliberately included in the application by the developer, the motivation for manifests on other platforms don’t apply.</p></div>
-<div class="paragraph"><p>On debuggable devices (<span class="monospaced">ro.debuggable</span> property exists and is non-zero, generally rooted or engineering builds) the loader will also search the directory <span class="monospaced">/data/local/debug/vulkan</span> and attempt to load layer libraries it finds there. This directory doesn’t exist by default. On Android N and later, because this location is writable by adb, SELinux policies prevent mapping code located here as executable. So to use layers from here, SELinux enforcement must be disabled: <span class="monospaced">adb shell setenforce 0</span>. This mechanism is not intended for application developers, only for IHV and OEM engineers working on test devices that don’t have private or sensitive data.</p></div>
-<div class="paragraph"><p>Our goal is to allow layers to be ported with only build-environment changes between Android and other platforms. For this to work, layers must properly implement things like <span class="monospaced">vkGetInstanceLayerProperties</span> and <span class="monospaced">vkGetInstanceExtensionProperties</span>, even though the LunarG loader doesn’t use them (it gets the information from manifests instead).</p></div>
-</div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_window_system_integration">2. Window System Integration</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>The <span class="monospaced">vk_wsi_swapchin</span> and <span class="monospaced">vk_wsi_device_swapchain</span> extensions are primarily be implemented by the platform and live in <span class="monospaced">libvulkan.so</span>. The <span class="monospaced">VkSwapchain</span> object and all interaction with <span class="monospaced">ANativeWindow</span> will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver’s <span class="monospaced">vkGetDeviceProcAddr</span> functions, after passing through any enabled layers.</p></div>
-<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The swapchain usage bits are defined as</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">enum</span></span> VkSwapchainImageUsageFlagBitsANDROID <span style="color: #FF0000">{</span>
- VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID <span style="color: #990000">=</span> <span style="color: #993399">0x00000001</span><span style="color: #990000">,</span>
- VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM <span style="color: #990000">=</span> <span style="color: #993399">0x7FFFFFFF</span>
-<span style="color: #FF0000">}</span> VkSwapchainImageUsageFlagBitsANDROID<span style="color: #990000">;</span>
-<span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="color: #008080">VkFlags</span> VkSwapchainImageUsageFlagsANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VKAPI_ATTR <span style="color: #008080">VkResult</span> <span style="color: #008080">VKAPI_CALL</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsage2ANDROID</span></span><span style="color: #990000">(</span>
- <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span>
- <span style="color: #008080">VkFormat</span> format<span style="color: #990000">,</span>
- <span style="color: #008080">VkImageUsageFlags</span> imageUsage<span style="color: #990000">,</span>
- <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> swapchainImageUsage<span style="color: #990000">,</span>
- uint64_t<span style="color: #990000">*</span> grallocConsumerUsage<span style="color: #990000">,</span>
- uint64_t<span style="color: #990000">*</span> grallocProducerUsage<span style="color: #990000">,</span>
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocConsumerUsage</span> and <span class="monospaced">*grallocProducerUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
-<div class="paragraph"><p>An older version of this function is deprecated but still supported for backwards compatibility; it will be used if <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> is not supported:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
- <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span>
- <span style="color: #008080">VkFormat</span> format<span style="color: #990000">,</span>
- <span style="color: #008080">VkImageUsageFlags</span> imageUsage<span style="color: #990000">,</span>
- <span style="color: #009900">int</span><span style="color: #990000">*</span> grallocUsage
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p><span class="monospaced">VkNativeBufferANDROID</span> is a <span class="monospaced">vkCreateImage</span> extension structure for creating an image backed by a gralloc buffer. This structure is provided to <span class="monospaced">vkCreateImage</span> in the <span class="monospaced">VkImageCreateInfo</span> structure chain. Calls to <span class="monospaced">vkCreateImage</span> with this structure will happen during the first call to <span class="monospaced">vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</span>. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a <span class="monospaced">VkImage</span> for each one.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
- <span style="color: #008080">VkStructureType</span> sType<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID</span></span>
- <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> <span style="color: #009900">void</span><span style="color: #990000">*</span> pNext<span style="color: #990000">;</span>
-
- <span style="font-style: italic"><span style="color: #9A1900">// Buffer handle and stride returned from gralloc alloc()</span></span>
- <span style="color: #008080">buffer_handle_t</span> handle<span style="color: #990000">;</span>
- <span style="color: #009900">int</span> stride<span style="color: #990000">;</span>
-
- <span style="font-style: italic"><span style="color: #9A1900">// Gralloc format and usage requested when the buffer was allocated.</span></span>
- <span style="color: #009900">int</span> format<span style="color: #990000">;</span>
- <span style="color: #009900">int</span> usage<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// deprecated</span></span>
- <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
- <span style="color: #008080">uint64_t</span> consumer<span style="color: #990000">;</span>
- <span style="color: #008080">uint64_t</span> producer<span style="color: #990000">;</span>
- <span style="color: #FF0000">}</span> usage2<span style="color: #990000">;</span>
-<span style="color: #FF0000">}</span> VkNativeBufferANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p>When creating a gralloc-backed image, the <span class="monospaced">VkImageCreateInfo</span> will have:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt> .imageType = VK_IMAGE_TYPE_2D
- .format = a VkFormat matching the format requested for the gralloc buffer
- .extent = the 2D dimensions requested for the gralloc buffer
- .mipLevels = 1
- .arraySize = 1
- .samples = 1
- .tiling = VK_IMAGE_TILING_OPTIMAL
- .usage = VkSwapChainCreateInfoWSI::imageUsageFlags
- .flags = 0
- .sharingMode = VkSwapChainCreateInfoWSI::sharingMode
- .queueFamilyCount = VkSwapChainCreateInfoWSI::queueFamilyCount
- .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices</tt></pre></div></div>
-<div class="paragraph"><p>Additionally, when any swapchain image usage flags are required for the swapchain, the platform will provide a <span class="monospaced">VkSwapchainImageCreateInfoANDROID</span> extension structure in the <span class="monospaced">VkImageCreateInfo</span> chain provided to <span class="monospaced">vkCreateImage</span>, containing the swapchain image usage flags:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
- <span style="color: #008080">VkStructureType</span> sType<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID</span></span>
- <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> <span style="color: #009900">void</span><span style="color: #990000">*</span> pNext<span style="color: #990000">;</span>
-
- <span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> usage<span style="color: #990000">;</span>
-<span style="color: #FF0000">}</span> VkSwapchainImageCreateInfoANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p><span class="monospaced">vkAcquireImageANDROID</span> acquires ownership of a swapchain image and imports an
-externally-signalled native fence into both an existing VkSemaphore object
-and an existing VkFence object:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkAcquireImageANDROID</span></span><span style="color: #990000">(</span>
- <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span>
- <span style="color: #008080">VkImage</span> image<span style="color: #990000">,</span>
- <span style="color: #009900">int</span> nativeFenceFd<span style="color: #990000">,</span>
- <span style="color: #008080">VkSemaphore</span> semaphore<span style="color: #990000">,</span>
- VkFence fence
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>This function is called during <span class="monospaced">vkAcquireNextImageWSI</span> to import a native
-fence into the <span class="monospaced">VkSemaphore</span> and <span class="monospaced">VkFence</span> objects provided by the
-application. Both semaphore and fence objects are optional in this call. The
-driver may also use this opportunity to recognize and handle any external
-changes to the gralloc buffer state; many drivers won’t need to do anything
-here. This call puts the <span class="monospaced">VkSemaphore</span> and <span class="monospaced">VkFence</span> into the same "pending"
-state as <span class="monospaced">vkQueueSignalSemaphore</span> and <span class="monospaced">vkQueueSubmit</span> respectively, so queues
-can wait on the semaphore and the application can wait on the fence. Both
-objects become signalled when the underlying native fence signals; if the
-native fence has already signalled, then the semaphore will be in the signalled
-state when this function returns. The driver takes ownership of the fence fd
-and is responsible for closing it when no longer needed. It must do so even if
-neither a semaphore or fence object is provided, or even if
-<span class="monospaced">vkAcquireImageANDROID</span> fails and returns an error. If <span class="monospaced">fenceFd</span> is -1, it
-is as if the native fence was already signalled.</p></div>
-<div class="paragraph"><p><span class="monospaced">vkQueueSignalReleaseImageANDROID</span> prepares a swapchain image for external use, and creates a native fence and schedules it to be signalled when prior work on the queue has completed.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkQueueSignalReleaseImageANDROID</span></span><span style="color: #990000">(</span>
- <span style="color: #008080">VkQueue</span> queue<span style="color: #990000">,</span>
- <span style="color: #008080">uint32_t</span> waitSemaphoreCount<span style="color: #990000">,</span>
- <span style="font-weight: bold"><span style="color: #0000FF">const</span></span> VkSemaphore<span style="color: #990000">*</span> pWaitSemaphores<span style="color: #990000">,</span>
- <span style="color: #008080">VkImage</span> image<span style="color: #990000">,</span>
- <span style="color: #009900">int</span><span style="color: #990000">*</span> pNativeFenceFd
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>This will be called during <span class="monospaced">vkQueuePresentWSI</span> on the provided queue. Effects are similar to <span class="monospaced">vkQueueSignalSemaphore</span>, except with a native fence instead of a semaphore. The native fence must: not signal until the <span class="monospaced">waitSemaphoreCount</span> semaphores in <span class="monospaced">pWaitSemaphores</span> have signaled. Unlike <span class="monospaced">vkQueueSignalSemaphore</span>, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set <span class="monospaced">*pNativeFenceFd</span> to -1. The file descriptor returned in <span class="monospaced">*pNativeFenceFd</span> is owned and will be closed by the caller. Many drivers will be able to ignore the <span class="monospaced">image</span> parameter, but some may need to prepare CPU-side data structures associated with a gralloc buffer for use by external image consumers. Preparing buffer contents for use by external consumers should have been done asynchronously as part of transitioning the image to <span class="monospaced">VK_IMAGE_LAYOUT_PRESENT_SRC_KHR</span>.</p></div>
-<div class="paragraph"><p>If <span class="monospaced">image</span> was created with <span class="monospaced">VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID</span>, then the driver must tolerate <span class="monospaced">vkQueueSignalReleaseImageANDROID</span> being called repeatedly without intervening calls to <span class="monospaced">vkAcquireImageANDROID</span>.</p></div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_history">3. History</h2>
-<div class="sectionbody">
-<div class="olist arabic"><ol class="arabic">
-<li>
-<p>
-<strong>2015-07-08</strong> Initial version
-</p>
-</li>
-<li>
-<p>
-<strong>2015-08-16</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Renamed to Implementor’s Guide
-</p>
-</li>
-<li>
-<p>
-Wording and formatting changes
-</p>
-</li>
-<li>
-<p>
-Updated based on resolution of Khronos bug 14265
-</p>
-</li>
-<li>
-<p>
-Deferred support for multiple drivers
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2015-11-04</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Added vkGetSwapchainGrallocUsageANDROID
-</p>
-</li>
-<li>
-<p>
-Replaced vkImportNativeFenceANDROID and vkQueueSignalNativeFenceANDROID
- with vkAcquireImageANDROID and vkQueueSignalReleaseImageANDROID, to allow
- drivers to known the ownership state of swapchain images.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2015-12-03</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Added a VkFence parameter to vkAcquireImageANDROID corresponding to the
- parameter added to vkAcquireNextImageKHR.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2016-01-08</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Added waitSemaphoreCount and pWaitSemaphores parameters to vkQueueSignalReleaseImageANDROID.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2016-06-17</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Updates to reflect final behavior, closed some TBDs now that they’ve BDed.
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2017-01-06</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Extension version 6
-</p>
-</li>
-<li>
-<p>
-Added VkSwapchainImageUsageFlagBitsANDROID
-</p>
-</li>
-<li>
-<p>
-Added vkGetSwapchainGrallocUsage2ANDROID
-</p>
-</li>
-<li>
-<p>
-Added VkSwapchainImageCreateInfoANDROID
-</p>
-</li>
-</ul></div>
-</li>
-<li>
-<p>
-<strong>2017-02-09</strong>
-</p>
-<div class="ulist"><ul>
-<li>
-<p>
-Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
-</p>
-</li>
-</ul></div>
-</li>
-</ol></div>
-</div>
-</div>
-</div>
-<div id="footnotes"><hr></div>
-<div id="footer">
-<div id="footer-text">
-Version 5<br>
-Last updated 2017-02-09 22:40:30 PST
-</div>
-</div>
-</body>
-</html>
diff --git a/vulkan/include/vulkan/vulkan_android.h b/vulkan/include/vulkan/vulkan_android.h
index 42521d9..07aaeda 100644
--- a/vulkan/include/vulkan/vulkan_android.h
+++ b/vulkan/include/vulkan/vulkan_android.h
@@ -56,7 +56,7 @@
#define VK_ANDROID_external_memory_android_hardware_buffer 1
struct AHardwareBuffer;
-#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 2
+#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer"
typedef struct VkAndroidHardwareBufferUsageANDROID {
diff --git a/vulkan/include/vulkan/vulkan_core.h b/vulkan/include/vulkan/vulkan_core.h
index 6e5ea80..a28661f 100644
--- a/vulkan/include/vulkan/vulkan_core.h
+++ b/vulkan/include/vulkan/vulkan_core.h
@@ -43,7 +43,7 @@
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
// Version of this file
-#define VK_HEADER_VERSION 68
+#define VK_HEADER_VERSION 76
#define VK_NULL_HANDLE 0
@@ -147,6 +147,7 @@
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
VK_ERROR_INVALID_SHADER_NV = -1000012000,
+ VK_ERROR_FRAGMENTATION_EXT = -1000161000,
VK_ERROR_NOT_PERMITTED_EXT = -1000174001,
VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
@@ -349,6 +350,11 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
+ VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001,
+ VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004,
VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000,
@@ -377,10 +383,18 @@
VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000,
VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,
@@ -1496,12 +1510,14 @@
typedef enum VkDescriptorSetLayoutCreateFlagBits {
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = 0x00000002,
VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkDescriptorSetLayoutCreateFlagBits;
typedef VkFlags VkDescriptorSetLayoutCreateFlags;
typedef enum VkDescriptorPoolCreateFlagBits {
VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
+ VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = 0x00000002,
VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkDescriptorPoolCreateFlagBits;
typedef VkFlags VkDescriptorPoolCreateFlags;
@@ -2704,6 +2720,16 @@
uint32_t firstInstance;
} VkDrawIndirectCommand;
+typedef struct VkBaseOutStructure {
+ VkStructureType sType;
+ struct VkBaseOutStructure* pNext;
+} VkBaseOutStructure;
+
+typedef struct VkBaseInStructure {
+ VkStructureType sType;
+ const struct VkBaseInStructure* pNext;
+} VkBaseInStructure;
+
typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator);
@@ -3736,6 +3762,7 @@
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020,
VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040,
VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080,
+ VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100,
VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkSubgroupFeatureFlagBits;
typedef VkFlags VkSubgroupFeatureFlags;
@@ -5095,7 +5122,7 @@
#define VK_KHR_maintenance1 1
-#define VK_KHR_MAINTENANCE1_SPEC_VERSION 1
+#define VK_KHR_MAINTENANCE1_SPEC_VERSION 2
#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR;
@@ -5560,6 +5587,70 @@
+#define VK_KHR_get_display_properties2 1
+#define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2"
+
+typedef struct VkDisplayProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayPropertiesKHR displayProperties;
+} VkDisplayProperties2KHR;
+
+typedef struct VkDisplayPlaneProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayPlanePropertiesKHR displayPlaneProperties;
+} VkDisplayPlaneProperties2KHR;
+
+typedef struct VkDisplayModeProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayModePropertiesKHR displayModeProperties;
+} VkDisplayModeProperties2KHR;
+
+typedef struct VkDisplayPlaneInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayModeKHR mode;
+ uint32_t planeIndex;
+} VkDisplayPlaneInfo2KHR;
+
+typedef struct VkDisplayPlaneCapabilities2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayPlaneCapabilitiesKHR capabilities;
+} VkDisplayPlaneCapabilities2KHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlaneProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModeProperties2KHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayProperties2KHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayPlaneProperties2KHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ uint32_t* pPropertyCount,
+ VkDisplayModeProperties2KHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo,
+ VkDisplayPlaneCapabilities2KHR* pCapabilities);
+#endif
+
#define VK_KHR_dedicated_allocation 1
#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3
#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation"
@@ -5715,6 +5806,33 @@
VkDescriptorSetLayoutSupport* pSupport);
#endif
+#define VK_KHR_draw_indirect_count 1
+#define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
+#define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count"
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+#endif
+
#define VK_EXT_debug_report 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
@@ -7230,6 +7348,95 @@
void* pData);
#endif
+#define VK_EXT_descriptor_indexing 1
+#define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
+#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+
+
+typedef enum VkDescriptorBindingFlagBitsEXT {
+ VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = 0x00000001,
+ VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = 0x00000002,
+ VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = 0x00000004,
+ VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = 0x00000008,
+ VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDescriptorBindingFlagBitsEXT;
+typedef VkFlags VkDescriptorBindingFlagsEXT;
+
+typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t bindingCount;
+ const VkDescriptorBindingFlagsEXT* pBindingFlags;
+} VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderInputAttachmentArrayDynamicIndexing;
+ VkBool32 shaderUniformTexelBufferArrayDynamicIndexing;
+ VkBool32 shaderStorageTexelBufferArrayDynamicIndexing;
+ VkBool32 shaderUniformBufferArrayNonUniformIndexing;
+ VkBool32 shaderSampledImageArrayNonUniformIndexing;
+ VkBool32 shaderStorageBufferArrayNonUniformIndexing;
+ VkBool32 shaderStorageImageArrayNonUniformIndexing;
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexing;
+ VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing;
+ VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing;
+ VkBool32 descriptorBindingUniformBufferUpdateAfterBind;
+ VkBool32 descriptorBindingSampledImageUpdateAfterBind;
+ VkBool32 descriptorBindingStorageImageUpdateAfterBind;
+ VkBool32 descriptorBindingStorageBufferUpdateAfterBind;
+ VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind;
+ VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind;
+ VkBool32 descriptorBindingUpdateUnusedWhilePending;
+ VkBool32 descriptorBindingPartiallyBound;
+ VkBool32 descriptorBindingVariableDescriptorCount;
+ VkBool32 runtimeDescriptorArray;
+} VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxUpdateAfterBindDescriptorsInAllPools;
+ VkBool32 shaderUniformBufferArrayNonUniformIndexingNative;
+ VkBool32 shaderSampledImageArrayNonUniformIndexingNative;
+ VkBool32 shaderStorageBufferArrayNonUniformIndexingNative;
+ VkBool32 shaderStorageImageArrayNonUniformIndexingNative;
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative;
+ VkBool32 robustBufferAccessUpdateAfterBind;
+ VkBool32 quadDivergentImplicitLod;
+ uint32_t maxPerStageDescriptorUpdateAfterBindSamplers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages;
+ uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages;
+ uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments;
+ uint32_t maxPerStageUpdateAfterBindResources;
+ uint32_t maxDescriptorSetUpdateAfterBindSamplers;
+ uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers;
+ uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+ uint32_t maxDescriptorSetUpdateAfterBindSampledImages;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageImages;
+ uint32_t maxDescriptorSetUpdateAfterBindInputAttachments;
+} VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
+
+typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t descriptorSetCount;
+ const uint32_t* pDescriptorCounts;
+} VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+
+typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupportEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxVariableDescriptorCount;
+} VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
+
+
+
#define VK_EXT_shader_viewport_index_layer 1
#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1
#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
@@ -7293,6 +7500,75 @@
VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties);
#endif
+#define VK_AMD_buffer_marker 1
+#define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1
+#define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker"
+
+typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ uint32_t marker);
+#endif
+
+#define VK_AMD_shader_core_properties 1
+#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 1
+#define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties"
+
+typedef struct VkPhysicalDeviceShaderCorePropertiesAMD {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t shaderEngineCount;
+ uint32_t shaderArraysPerEngineCount;
+ uint32_t computeUnitsPerShaderArray;
+ uint32_t simdPerComputeUnit;
+ uint32_t wavefrontsPerSimd;
+ uint32_t wavefrontSize;
+ uint32_t sgprsPerSimd;
+ uint32_t minSgprAllocation;
+ uint32_t maxSgprAllocation;
+ uint32_t sgprAllocationGranularity;
+ uint32_t vgprsPerSimd;
+ uint32_t minVgprAllocation;
+ uint32_t maxVgprAllocation;
+ uint32_t vgprAllocationGranularity;
+} VkPhysicalDeviceShaderCorePropertiesAMD;
+
+
+
+#define VK_EXT_vertex_attribute_divisor 1
+#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 1
+#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor"
+
+typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxVertexAttribDivisor;
+} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT;
+
+typedef struct VkVertexInputBindingDivisorDescriptionEXT {
+ uint32_t binding;
+ uint32_t divisor;
+} VkVertexInputBindingDivisorDescriptionEXT;
+
+typedef struct VkPipelineVertexInputDivisorStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t vertexBindingDivisorCount;
+ const VkVertexInputBindingDivisorDescriptionEXT* pVertexBindingDivisors;
+} VkPipelineVertexInputDivisorStateCreateInfoEXT;
+
+
+
+#define VK_NV_shader_subgroup_partitioned 1
+#define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1
+#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
+
+
#ifdef __cplusplus
}
#endif
diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp
index 7650e0c..629ebb1 100644
--- a/vulkan/libvulkan/api_gen.cpp
+++ b/vulkan/libvulkan/api_gen.cpp
@@ -553,7 +553,11 @@
"vkEnumeratePhysicalDeviceGroups",
"vkEnumeratePhysicalDeviceGroupsKHR",
"vkEnumeratePhysicalDevices",
+ "vkGetDisplayModeProperties2KHR",
+ "vkGetDisplayPlaneCapabilities2KHR",
"vkGetInstanceProcAddr",
+ "vkGetPhysicalDeviceDisplayPlaneProperties2KHR",
+ "vkGetPhysicalDeviceDisplayProperties2KHR",
"vkGetPhysicalDeviceExternalBufferProperties",
"vkGetPhysicalDeviceExternalBufferPropertiesKHR",
"vkGetPhysicalDeviceExternalFenceProperties",